题目重点:把localArea定义为向外相邻比较的半径,预计算递增/递减长度,处理端点、平台及半径为零。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练按从候选向外的连续相邻值比较,不任意跳过元素选子序列;返回下标。
- localArea为非负整数,某侧无元素时该侧条件真;半径0时全部位置符合。
- 严格下降不允许相等。若正式返回峰值或使用非连续subsequence,需另改输出或判定合同。
解题路线
- 相邻严格峰值求和变体只看内部节点 i=1..n−2,要求值大于左右相邻,并累加峰值而非下标。与允许端点的 localArea 合同分开:示例[2,3,1,5,4]内部峰3/5,和8。代码另提供strict_interior_peak_sum,不用带端点的函数直接求和。
- 直接对每个i检查半径R范围的相邻关系需O(nR)。因为各窗口大量重叠,可以预计算截至i左侧连续递增的边数L[i],及从i右侧连续递减的边数D[i]。
- 向左走是值依次下降,等价于沿数组从左向右到i严格上升。若a[i−1]<a[i]则L[i]=L[i−1]+1,否则0;左侧需要min(R,i)条合法边。
- 从右往左算D:若a[i]>a[i+1]则D[i]=D[i+1]+1,否则0。右侧需要min(R,n−1−i)条边。这两个长度条件同时满足即输出i。
- 条件足够性来自连续run:至少所需边数说明窗口内每条边均严格正确;必要性是窗口内若有任何坏边,连续长度会在那条边归零,无法达到所需长度。
- 端点不能一律排除,因为合同明确不足半径取现有元素。单元素数组两侧均空,对任意非负半径都合格;严格平台中的相等边使对应run断开。
- 文字中的subsequences容易让人以为可以跳点,正式面试要用[a,b,c]的小例确认。本实现采用连续片段合同并单列这个边界;没有凭“局部最大”名称替换成只比较相邻两点。
手动走一遍
[1,3,2,1]、R=2:下标1向左只有1个值,3>1;向右3>2>1,合格。下标3右侧空,但往左1>2不成立,不合格。R=0则[0,1,2,3]都符合。[2,2]、R=1无峰。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Return peak indices. From a candidate outward, all available comparisons
within radius local_area must decrease strictly. Endpoints may be peaks.
"""
def local_peak_indices(values, local_area):
if not isinstance(local_area, int) or isinstance(local_area, bool) or local_area < 0:
raise ValueError("nonnegative integer radius required")
n = len(values)
increasing = [0] * n
decreasing = [0] * n
for i in range(1, n):
if values[i - 1] < values[i]:
increasing[i] = increasing[i - 1] + 1
for i in range(n - 2, -1, -1):
if values[i] > values[i + 1]:
decreasing[i] = decreasing[i + 1] + 1
return [i for i in range(n)
if increasing[i] >= min(local_area, i)
and decreasing[i] >= min(local_area, n - 1 - i)]
def strict_interior_peak_sum(values):
"""Immediate neighbors only, endpoints excluded; sum values, not indices."""
return sum(values[i] for i in range(1, len(values)-1)
if values[i] > values[i-1] and values[i] > values[i+1])
复杂度
O(n)时间,左右run数组与结果O(n)空间。若只要计数,可不保存输出;还可用坏边前缀和或流式滑动检查降低工作空间,但需保持边界合同。
易错点与追问
容易失分的边界
- 向左严格下降写成原数组向右下降。
- 无条件排除端点。
- 把相等当严格。
- 只看邻居忽略localArea。
继续深挖
- 若返回值不是位置如何处理重复?
- R极大时怎样避免越界?
- 可否用坏边前缀和实现?
- 流式延迟R个元素怎样输出?
