LC-1827. 最少操作使数组递增(贪心)

1827. 最少操作使数组递增

难度简单37

给你一个整数数组 nums下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1

  • 比方说,如果 nums = [1,2,3] ,你可以选择增加 nums[1] 得到 nums = [1,**3**,3]

请你返回使 nums 严格递增最少 操作次数。

我们称数组 nums严格递增的 ,当它满足对于所有的 0 <= i < nums.length - 1 都有 nums[i] < nums[i+1] 。一个长度为 1 的数组是严格递增的一种特殊情况。

示例 1:

输入:nums = [1,1,1]
输出:3
解释:你可以进行如下操作:
1) 增加 nums[2] ,数组变为 [1,1,2] 。
2) 增加 nums[1] ,数组变为 [1,2,2] 。
3) 增加 nums[2] ,数组变为 [1,2,3] 。

示例 2:

输入:nums = [1,5,2,4,1]
输出:14

示例 3:

输入:nums = [8]
输出:0

提示:

  • 1 <= nums.length <= 5000
  • 1 <= nums[i] <= 104

贪心

每一项,要么变成前一项加1(不够大),要么不变(够大了)

class Solution {
    public int minOperations(int[] nums) { 
        int res = 0;
        int min = nums[0]+1;
        for(int i = 1; i < nums.length; i++){
            if(nums[i] < min){
                res += min-nums[i];
                min += 1;
            }else{
                min = nums[i]+1;
            }
            
        }
        return res;
    }
}

拓展

如果不限制对某个数进行+1 而是允许+1 或者-1 。那么本题怎么该如何解呢?

相似题目:2111. 使数组 K 递增的最少操作次数

如果题目里的K递增的定义被改成严格递增,是不能用分组然后求最长递增子序列来做的,因为题目另一个限制条件是数组里必须存正整数,那么类似2,1,2,3,4这样的序列是不能改成0,1,2,3,4的,这种情况下难道只能暴力求解了吗?

题解:0x3f

把每个数减去其下标,然后对所有正整数求最长非降子序列。

举个例子,现在每 k k k 个数选一个数,假设选出来的数组是 [ 3 , 2 , 4 , 5 , 5 , 6 , 6 ] [3,2,4,5,5,6,6] [3,2,4,5,5,6,6]

每个数减去其下标后就是 [ 3 , 1 , 2 , 2 , 1 , 1 , 0 ] [3,1,2,2,1,1,0] [3,1,2,2,1,1,0]

对这个数组中的正整数求最长非降子序列,那就是 [ 1 , 1 , 1 ] [1,1,1] [1,1,1] 了,对应原始数组的 [ ∗ , 2 , ∗ , ∗ , 5 , 6 , ∗ ] [*,2,*,*,5,6,*] [,2,,,5,6,],这三个数字保留,其余数字修改完成后就是 [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] [1,2,3,4,5,6,7] [1,2,3,4,5,6,7],符合严格递增且均为正整数的要求。

注:上述减去下标的技巧,主要是为了能让保留的数字之间可以容纳严格递增的数字。否则,若直接按照最长严格递增子序列的求法,会得到例如 [ ∗ , 2 , 4 , 5 , ∗ , 6 , ∗ ] [*,2,4,5,*,6,*] [,2,4,5,,6,] 这样的错误结果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值