SWE · Coding

TikTok 连续子数组:最大 min+max 为什么只看相邻对?

对长度至少2的任意区间给出相邻对上界见证,消除双重枚举和单调队列的必要。

题目重点:对长度至少2的任意区间给出相邻对上界见证,消除双重枚举和单调队列的必要。

题意与假设

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

  • 长度至少2,数组不足2时训练返回None表示无可行区间。
  • 返回和值;如要返回区间,保留达到最大相邻和的下标即可。
  • 题目为正整数,但下面证明对任意有序可加数值也成立;示例穷举包括负数作额外核对。

解题路线

  1. 固定任意合法区间,最大元素M所在位置一定有至少一个仍在区间里的相邻元素x,因为区间长度≥2。该区间最小值m≤x,于是m+M≤x+M。
  2. 这对相邻元素本身构成合法长度2子数组,其min+max恰等于两数之和。因此每个更长区间的目标值,都不超过某个相邻区间的值。
  3. 反过来所有相邻对也是候选区间,所以最大相邻和≤全体区间最优值;结合上界,二者相等。这是缩短到2元素仍不变差的证明,而非观察样例后猜贪心。
  4. 只扫描相邻和并取最大即可,无需维护整个窗口的min/max,也无需枚举最大值和全局第二大值。全局最大的两个数若不相邻,不保证它们之间的区间最小值够大。
  5. 边界n=2只有一个候选,n=0/1没有。若增加最小区间长度3或指定固定长度k,上面的相邻对子区间不再合法,算法立即失效,必须重新建模。
  6. 若要求最优最长区间,返回一对虽然达到值但不一定满足tie-break;需额外分析可向哪边扩展而保持min+max。题目只要值时不用引入这个不同目标。

手动走一遍

[5,12,9,6,4]相邻和17、21、15、10,答案21,由[12,9]取得。全区间min4+max12=16。[100,1,99]全局两大是100/99但不相邻,合法最优值101,而不是199。

Python 参考实现

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

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

"""Largest min+max over nonempty contiguous subarrays of length >=2.
No result when the array has fewer than two entries.
"""


def largest_min_plus_max(values):
    if len(values) < 2:
        return None
    return max(values[i - 1] + values[i] for i in range(1, len(values)))

复杂度

O(n)时间、O(1)额外空间,不含输入;每个相邻对只算一次。整数求和可能溢出,用足够宽类型。

易错点与追问

容易失分的边界

  • 直接相加全局最大两数。
  • 允许长度1导致答案变成2·max。
  • 加单调队列却仍漏证明。
  • 长度合同改变仍沿用相邻和。

继续深挖

  • 若限定长度恰好K怎么做?
  • 如何返回区间并定义tie-break?
  • 最小长度为3时能否继续缩短?
  • 若目标是max−min,还能用此证明吗?
✓已复制微信号!