题目重点:对长度至少2的任意区间给出相邻对上界见证,消除双重枚举和单调队列的必要。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 长度至少2,数组不足2时训练返回None表示无可行区间。
- 返回和值;如要返回区间,保留达到最大相邻和的下标即可。
- 题目为正整数,但下面证明对任意有序可加数值也成立;示例穷举包括负数作额外核对。
解题路线
- 固定任意合法区间,最大元素M所在位置一定有至少一个仍在区间里的相邻元素x,因为区间长度≥2。该区间最小值m≤x,于是m+M≤x+M。
- 这对相邻元素本身构成合法长度2子数组,其min+max恰等于两数之和。因此每个更长区间的目标值,都不超过某个相邻区间的值。
- 反过来所有相邻对也是候选区间,所以最大相邻和≤全体区间最优值;结合上界,二者相等。这是缩短到2元素仍不变差的证明,而非观察样例后猜贪心。
- 只扫描相邻和并取最大即可,无需维护整个窗口的min/max,也无需枚举最大值和全局第二大值。全局最大的两个数若不相邻,不保证它们之间的区间最小值够大。
- 边界n=2只有一个候选,n=0/1没有。若增加最小区间长度3或指定固定长度k,上面的相邻对子区间不再合法,算法立即失效,必须重新建模。
- 若要求最优最长区间,返回一对虽然达到值但不一定满足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,还能用此证明吗?
