不能直接用 std::max_element 找最长等差数列,因为它只能比较元素大小,无法判断子序列或子数组的公差一致性;连续情况可用双指针 o(n),非连续必须二维 dp+哈希优化 o(n²)。

为什么不能直接用 std::max_element 找最长等差数列
因为等差数列不是单个元素的属性,而是子序列(不一定是连续)或子数组(连续)的结构特征。std::max_element 只能比大小,无法判断公差一致性。常见误判是把“最长连续等差子数组”当成“最长(任意位置)等差子序列”,两者解法完全不同——前者可用双指针 O(n),后者必须动态规划 O(n²)。
连续等差子数组:用双指针维护当前公差
如果题目明确要求“连续”,比如数组 [1,3,5,7,2,4] 中最长连续等差段是 [1,3,5,7](长度 4,公差 2),那就不用 DP:
- 从索引 1 开始遍历,计算
diff = arr[i] - arr[i-1] - 用变量
curr_len记录当前连续段长度,max_len记全局最大值 - 若
arr[i] - arr[i-1] == diff,则curr_len++;否则重置curr_len = 2、更新diff - 注意边界:长度 ≤ 2 的数组直接返回原长
示例代码核心逻辑:
int longestArithSeqLength(vector<int>& arr) {
if (arr.size() <h3>非连续等差子序列:必须用二维 DP + 哈希优化</h3>
<p>LeetCode 1027 题型:在 <code>[9,4,7,2,10]</code> 中找最长等差子序列(答案是 <code>[4,7,10]</code> 或 <code>[9,7,2]</code>,长度 3)。暴力枚举所有子序列是指数级,正确做法是:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master"><img
src="https://img.php.cn/upload/skill/000/000/081/179051228971575.jpg" alt="C++ Code Review Master" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="overflowclass">C++ Code Review Master</a>
<p class="overflowclass">组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>定义 <code>dp[i][diff]</code> 表示以 <code>arr[i]</code> 结尾、公差为 <code>diff</code> 的最长子序列长度</li>
<li>但 <code>diff</code> 可能很大(如 <code>INT_MIN</code> 到 <code>INT_MAX</code>),不能开二维数组,改用 <code>unordered_map<int int></int></code> 存每个下标对应的公差映射</li>
<li>对每个 <code>i</code>,遍历 <code>j</code> 从 <code>0</code> 到 <code>i-1</code>,算 <code>diff = arr[i] - arr[j]</code>,然后 <code>dp[i][diff] = dp[j][diff] + 1</code>(若 <code>dp[j][diff]</code> 不存在则为 2)</li>
<li>时间复杂度 O(n²),空间 O(n²) —— 每个 <code>i</code> 最多存 n 个不同公差</li>
</ul>
<p>关键细节:<code>diff</code> 是 <code>int</code> 类型,但 C++ 中负数哈希无问题;不要用 <code>map</code>(log n 开销),坚持用 <code>unordered_map</code>。</p>
<h3>容易被忽略的边界和性能坑</h3>
<p>实际写的时候这几个点最常出错:</p>
<ul>
<li>输入为空或只有 1 个元素时,直接返回 <code>arr.size()</code>,别进循环</li>
<li>公差为 0 的情况必须支持(如 <code>[1,1,1,2,2]</code>,最长是 3 个 1),<code>diff == 0</code> 不影响哈希键</li>
<li>用 <code>vector<unordered_map int>> dp(n)</unordered_map></code> 初始化,别写成 <code>dp[i].insert({diff, 2})</code> 而漏掉已有值——要写 <code>dp[i][diff] = max(dp[i][diff], dp[j][diff] + 1)</code>
</li>
<li>LeetCode 测试用例含大数组(n ≈ 1000),O(n³) 暴力必超时,DP 外层循环不能嵌套查找</li>
</ul>
<p>真正卡住人的往往不是算法思路,而是 <code>dp[j].count(diff)</code> 判断写错位置,或者把 <code>dp[i][diff]</code> 初始化成 1 而不是 2。</p></int>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










