局部极大值指数组中严格大于相邻元素的元素;C++中需分边界处理:首元素仅与右邻比较,尾元素仅与左邻比较,中间元素需同时大于左右邻,避免越界访问。

什么是局部极大值,C++里怎么定义边界条件
局部极大值是指数组中某个元素,严格大于它左右相邻的元素。对长度为 n 的数组 arr,索引 i 是局部极大值当且仅当:
-
i不是首尾(即1 <= i <= n-2),且arr[i] > arr[i-1]且arr[i] > arr[i+1]
首尾元素也能算——但需单独约定:通常题目会说明“首尾可视为局部极大值当且仅当它大于唯一邻居”。比如 arr[0] 是局部极大值 ⇔ arr[0] > arr[1];arr[n-1] 是 ⇔ arr[n-1] > arr[n-2]
不处理边界直接访问 arr[i-1] 或 arr[i+1] 会导致越界,这是最常踩的坑。
用 for 循环遍历,注意索引范围别写错
标准做法是分三段检查:左端点、中间、右端点。但更稳妥的是统一用带边界的循环 + 条件判断:
立即学习“C++免费学习笔记(深入)”;
- 先检查
arr.size() == 0或1的情况(空数组无解;单元素按题意可能算一个) - 对
i = 0:只比arr[1] - 对
i = arr.size()-1:只比arr[arr.size()-2] - 其余
i:同时比左右
for (int i = 0; i < arr.size(); ++i) {
bool isPeak = false;
if (i == 0 && arr.size() > 1 && arr[0] > arr[1])
isPeak = true;
else if (i == arr.size()-1 && arr.size() > 1 && arr[i] > arr[i-1])
isPeak = true;
else if (i > 0 && i < arr.size()-1 && arr[i] > arr[i-1] && arr[i] > arr[i+1])
isPeak = true;
if (isPeak) peaks.push_back(i);
}
别用 for (int i = 1; i < n-1; ++i) 一上来就跳过端点——除非你明确不需要端点结果。
用 std::vector 存索引还是值?返回多个时怎么选多数场景要的是索引位置(比如题目问“返回任意一个局部极大值的下标”),因为:
- 索引可用于后续操作(如删除、修改该位置)
- 值可能重复,索引才能唯一标识
- 题目约束常是“保证存在至少一个”,返回任一索引即可(此时可用早停优化)
如果只要一个结果,找到就 return i,不必遍历全部;如果要所有,就 push_back 到 vector<int></int>
注意:若数组有平台(连续相等最大值),比如 [1,3,3,3,1],中间三个 3 都不满足“严格大于”,所以都不是局部极大值——这点容易被忽略。
性能与边界组合容易出错的几个点
-
arr.size() == 1:此时没有邻居,是否算局部极大值取决于题意。LeetCode #162 默认算,但有些业务逻辑要求至少两个元素才判断
-
arr.size() == 2:两个元素互为唯一邻居,arr[0] 和 arr[1] 不可能同时是局部极大值,但可能有一个是(比如 [2,1] 中 0 是,[1,2] 中 1 是)
- 使用
size_t 作循环变量时,i-1 可能回绕成极大正数(导致越界访问),务必转成有符号类型或改用 int
真正麻烦的不是逻辑,而是不同题目对“局部极大值”的隐含定义不一致——动手前先确认端点是否参与、是否允许相等、是否只需一个答案。
多数场景要的是索引位置(比如题目问“返回任意一个局部极大值的下标”),因为:
- 索引可用于后续操作(如删除、修改该位置)
- 值可能重复,索引才能唯一标识
- 题目约束常是“保证存在至少一个”,返回任一索引即可(此时可用早停优化)
如果只要一个结果,找到就 return i,不必遍历全部;如果要所有,就 push_back 到 vector<int></int>
注意:若数组有平台(连续相等最大值),比如 [1,3,3,3,1],中间三个 3 都不满足“严格大于”,所以都不是局部极大值——这点容易被忽略。
性能与边界组合容易出错的几个点
-
arr.size() == 1:此时没有邻居,是否算局部极大值取决于题意。LeetCode #162 默认算,但有些业务逻辑要求至少两个元素才判断
-
arr.size() == 2:两个元素互为唯一邻居,arr[0] 和 arr[1] 不可能同时是局部极大值,但可能有一个是(比如 [2,1] 中 0 是,[1,2] 中 1 是)
- 使用
size_t 作循环变量时,i-1 可能回绕成极大正数(导致越界访问),务必转成有符号类型或改用 int
arr.size() == 1:此时没有邻居,是否算局部极大值取决于题意。LeetCode #162 默认算,但有些业务逻辑要求至少两个元素才判断arr.size() == 2:两个元素互为唯一邻居,arr[0] 和 arr[1] 不可能同时是局部极大值,但可能有一个是(比如 [2,1] 中 0 是,[1,2] 中 1 是)size_t 作循环变量时,i-1 可能回绕成极大正数(导致越界访问),务必转成有符号类型或改用 int
真正麻烦的不是逻辑,而是不同题目对“局部极大值”的隐含定义不一致——动手前先确认端点是否参与、是否允许相等、是否只需一个答案。


















