【Leetcode】1526. Minimum Number of Increments on Subarrays to Form a Target Array(配数学证明)

题目地址:

https://leetcode.com/problems/minimum-number-of-increments-on-subarrays-to-form-a-target-array/

给定一个长 n n n的目标数组 A A A,并且给定一个全是 0 0 0的长 n n n的数组作为初始数组,对初始数组可以进行这样的操作,每次选取一个子区间,将这个区间内的数都加 1 1 1。问要变成 A A A至少需要多少步。

其实答案等于 A [ 0 ] + ∑ i ≥ 1 max ⁡ { 0 , A [ i ] − A [ i − 1 ] } A[0]+\sum_{i\ge 1} \max\{0,A[i]-A[i-1]\} A[0]+i1max{0,A[i]A[i1]},因为对于连续下降的子段,代价就是那个最大值,而如果有上升,这个上升的差必须额外耗费操作。严格证明如下:

数学归纳法。如果 n = 1 n=1 n=1显然。假设对 n − 1 n-1 n1成立,当数组长 n n n的时候,如果 A [ n ] ≤ A [ n − 1 ] A[n]\le A[n-1] A[n]A[n1],根据归纳假设,存在上述代价的操作将 A [ 0 : n − 1 ] A[0:n-1] A[0:n1]变成 0 0 0,那么由于这个操作也把 A [ n − 1 ] A[n-1] A[n1]变成 0 0 0了,我们可以凡是含 A [ n − 1 ] A[n-1] A[n1]的操作都延伸到 A [ n ] A[n] A[n]恰好 A [ n ] A[n] A[n]次,这样顺便把 A [ n ] A[n] A[n]也变成 0 0 0了而操作次数不变,从而成立;如果 A [ n ] > A [ n − 1 ] A[n]> A[n-1] A[n]>A[n1],那么任何把 A A A变成 0 0 0数组的操作都会某一个时刻将 A [ n − 1 ] A[n-1] A[n1]变成 0 0 0,并且最优方案一定是顺便把 A [ n ] A[n] A[n]也减少 A [ n − 1 ] A[n-1] A[n1]这么多,我们调整操作次序,把单独对 A [ n : n ] A[n:n] A[n:n]的操作挪到最后,由归纳假设要将 A [ 0 : n − 1 ] A[0:n-1] A[0:n1]变成 0 0 0的方案的最少次数是上述值,那么还需要 A [ n ] − A [ n − 1 ] A[n]-A[n-1] A[n]A[n1]步再把 A [ n ] A[n] A[n]变成 0 0 0,从而结论也成立。

代码如下:

public class Solution {
    public int minNumberOperations(int[] target) {
        int res = target[0];
        for (int i = 1; i < target.length; i++) {
            if (target[i] > target[i - 1]) {
                res += target[i] - target[i - 1];
            }
        }
        
        return res;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值