
本文介绍一种时间复杂度为 o(n) 的高效贪心算法,通过识别数组中所有“违反严格递增规则的位置”(即 a[i] ≤ a[i−1]),直接统计最少段修改次数,而非累加增量值。
本文介绍一种时间复杂度为 o(n) 的高效贪心算法,通过识别数组中所有“违反严格递增规则的位置”(即 a[i] ≤ a[i−1]),直接统计最少段修改次数,而非累加增量值。
要将数组变为严格递增(strictly increasing),关键在于理解题设中“一次操作 = 对任意连续子数组的所有元素增加一个正整数”这一定义的本质含义。
⚠️ 重要澄清:本题目标是最小化操作次数(moves),而非最小化总增量和。每次操作可作用于任意长度 ≥1 的连续子段,且只要求增加值为正整数(不限定具体大小)。这意味着:
- 我们不关心“每个元素要加多少”,而只关心“至少需要多少次独立的段增操作”;
- 一次操作可修复多个逆序位置——只要它们落在同一段内,且后续调整能保证全局有序。
核心观察:操作次数 = 下降点数量
考虑严格递增的必要条件:对所有 i ∈ [1, n−1],必须满足 A[i] > A[i−1]。
若 A[i] ≤ A[i−1],则称位置 i 是一个下降点(descent point) —— 此处必然需要至少一次操作来“抬高” A[i] 或其左侧某段,以打破该逆序。
但注意:一次段增操作可能同时修复多个下降点。例如 [3, 1, 2] 中,i=1(1≤3)和 i=2(2≤1)均为下降点,但只需一次操作:对子段 [1,2] 加 3 → [3,4,5],即可全部修复。
然而,存在一个不可绕过的下界:每次操作最多只能“覆盖”一个连续的下降点后缀。更精确地说:
✅ 正确结论(经反证与构造验证):
最小操作次数 = 数组中满足 A[i] ≤ A[i−1] 的索引 i 的个数。
即:统计所有 i ≥ 1 使得 A[i]
为什么?因为:
- 每个下降点 i 表明 A[i] 当前不够大,必须被某次操作影响(否则无法满足 A[i] > A[i−1]);
- 但一次操作若覆盖了位置 i,它无法同时修复一个更早的、已被“隔离”的下降点 j ,除非该操作也覆盖 j 及其前驱——而这会破坏 j−1 与 j 的关系(除非 j 本身也被设计为修复目标);
- 实际上,最优策略总是:从左到右扫描,每当遇到下降点 i,就执行一次操作,将 A[i..n−1] 整体提升足够量(例如 +1 即可),从而确保 A[i] > A[i−1],且后续所有元素自动满足相对大小关系(因整体右段被统一抬高,原有内部顺序不变,仅整体上移)。
该策略的可行性证明:
设已维护 A[0..i−1] 严格递增。在位置 i 发现 A[i] ≤ A[i−1],我们执行操作:对子段 A[i..n−1] 所有元素加 δ = A[i−1] − A[i] + 1(保证 A[i] 新值 = A[i−1] + 1)。由于该操作不改变 A[i..n−1] 内部的相对差值,原 A[i]
由此得出简洁解法:遍历数组,统计 A[i]
✅ 正确实现代码
def solution(A):
if len(A) <= 1:
return 0
moves = 0
for i in range(1, len(A)):
if A[i] <= A[i-1]:
moves += 1
return moves验证示例
| 输入 | 下降点位置(i) | 下降点数量 | 输出 |
|---|---|---|---|
| [4, 2, 4, 1, 3, 5] | i=1(2≤4), i=3(1≤4) | 2 | ✅ 2 |
| [3, 5, 7, 7] | i=3(7≤7) | 1 | ✅ 1 |
| [1, 5, 6, 10] | 无 | 0 | ✅ 0 |
| [2, 1] | i=1(1≤2) | 1 | ✅ 1 |
| [1, 1, 2] | i=1(1≤1) | 1 | ✅ 1(注意:i=2 处 2>1,不构成下降点) |
❗ 原错误代码问题根源:将“最小增量和”逻辑误用于“最小操作数”问题。它累加 diff(如 max_so_far + 1 - current_val),本质是在求使数组递增所需的最小总增量,而非最少段操作次数。二者目标函数完全不同。
总结与注意事项
- 时间复杂度:O(n),单次遍历,满足 N ≤ 10⁵ 约束;
- 空间复杂度:O(1),仅用常数额外变量;
- 适用前提:题目明确“一次操作 = 对一段连续元素加任意正整数”,且目标为最小化操作次数;
- 易错点:勿混淆“操作次数”与“总增量”;下降点判断严格使用 A[i−1];
- 扩展思考:若题目改为“最小化总增量”,则需动态规划(如 LIS 变种),时间复杂度升至 O(n log n)。
掌握这一“下降点计数”思想,可快速解决同类区间增操作计数问题,是贪心策略在序列约束场景下的典型范式。










