SWE · Coding

Meta 局部最小值:相邻不同的坡度二分

在相邻值不同且边界视为正无穷的合同下,返回一个严格局部最小索引。

题目重点:在相邻值不同且边界视为正无穷的合同下,返回一个严格局部最小索引。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练values相邻不等,两端外侧虚拟+∞,strict local min小于存在的两邻;empty None、单元素0,允许任意一个局部最小。
  • 相等值/平台、端点是否允许没有完整细则,当前合同明确相邻不同而不声称涵盖所有变体。为保持O(logN)不全量校验前提。

解题路线

  1. 比较mid与mid+1:若向右下降,右半必包含局部谷底;否则向右上升,左半必包含。相邻不等避免平坡无法判断严格谷底。
  2. 更精确不变量:搜索区间外两端高度高于相应区间边界,或外侧+∞。下降选择右侧保留左边外高,上升选择左侧保留右边外高,单点时两邻均大即局部最小。
  3. 算法只返回局部而非全局最小,多个谷底选择由二分路径决定。不可对结果assert等于min(values)作为测试,应该核对其邻居关系。
  4. 相等允许时可能根本无严格局部最小,例如[2,2];若改为非严格≤,平台可返回但输出合同变了。找严格谷底含plateau需额外扫描/前提,不能继续承诺当前证明。

手动走一遍

[5,3,4,1,2]局部谷底index1或3都合法;[1,2,3]端点0合法,[3,2,1]端点2合法。边界若不允许,单调数组会无解,不能直接复用。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def local_minimum(values):
    """Adjacent values distinct; virtual outside values +infinity; any strict min.

    Empty ->None. Assumption not validated to preserve logarithmic query cost.
    """
    if not values:return None
    left=0;right=len(values)-1
    while left<right:
        middle=(left+right)//2
        if values[middle]>values[middle+1]:left=middle+1
        else:right=middle
    return left

复杂度

O(logN)比较/O(1)状态,在随机访问与相邻不等前提下。验证相邻不同本身O(N),如果接口承诺输入不可信,总成本含校验而非仅二分。

易错点与追问

容易失分的边界

  • 局部最小与全局最小混同。
  • 相等平台仍保证strict min存在,明显反例[2,2]。

继续深挖

  • 只允许内部局部最小时,怎样报告无解并改变边界证明?
  • 磁盘/链表无O(1)中点随机访问时,二分的真实访问成本如何算?
✓已复制微信号!