📌  相关文章
📜  最小增量减量使数组不递增(1)

📅  最后修改于: 2023-12-03 15:10:36.802000             🧑  作者: Mango

最小增量减量使数组不递增

有一个长度为 n 的数组 nums,每隔 k 个元素会出现一个下降的趋势,你需要通过比较相邻元素,使得最少增加或减少的数字个数,使得整个数组不递增(即存在相邻元素 a 和 b,满足 a <= b)。

思路

为了尽可能少地更改元素,我们可以保留下降趋势的最后一个元素,然后对前面的元素进行调整,使其不递减即可。具体而言,以两个下降趋势之间的元素为例,对于前一个下降趋势的最后一个元素 a 和后一个下降趋势的第一个元素 b,有两种情况:

  1. a <= b,此时我们需要将前一个下降趋势的最后一个元素增加到 b,即把 a 修改为 b。
  2. a > b,此时我们需要将后一个下降趋势的第一个元素减小到 a,即把 b 修改为 a。

然后,我们可以计算出所有需要修改的元素并返回即可。

代码
def minIncrementForNonDecreasing(nums: List[int], k: int) -> int:
    n = len(nums)
    last = [nums[i] for i in range(0, n, k)]
    inc = [0] * len(last)
    for i in range(1, len(last)):
        inc[i] = max(0, last[i - 1] + 1 - last[i])
    for i in range(len(last) - 2, -1 , -1):
        inc[i] = max(inc[i], max(0, last[i + 1] + 1 - last[i]) - k)
    return sum(inc)

代码中,我们首先将数组按照每隔 k 个元素为一组拆分成多个下降趋势和上升趋势,并用 last 数组保存下降趋势的最后一个元素。然后,我们根据上述思路计算出需要更改的元素个数,并返回即可。

总结

本题的关键在于找到最小修改的规律,即保留下降趋势的最后一个元素,然后优先调整前一个下降趋势的最后一个元素即可。在实现时,我们需要注意边界条件的处理以及代码的可读性和简洁性。