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
。那么本题怎么该如何解呢?
如果题目里的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,∗] 这样的错误结果。