LeetCode 330.按要求补齐数组
给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。
示例 1:
输入: nums = [1,3], n = 6
输出: 1
解释:
根据 nums 里现有的组合 [1], [3], [1,3],可以得出 1, 3, 4。
现在如果我们将 2 添加到 nums 中, 组合变为: [1], [2], [3], [1,3], [2,3], [1,2,3]。
其和可以表示数字 1, 2, 3, 4, 5, 6,能够覆盖 [1, 6] 区间里所有的数。
所以我们最少需要添加一个数字。
示例 2:
输入: nums = [1,5,10], n = 20
输出: 2
解释: 我们需要添加 [2, 4]。
示例 3:
输入: nums = [1,2,2], n = 5
输出: 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/patching-array
问题分析: 就拿nums[1,5,10],n=10来举例子吧
- 首先pos指向第一个元素,而我们要填的是1,刚好,则跳过,此时能表示的最大范围是maxSum=1
- pos+1,指向5,而我们此时要填的数是2,不能表示,所以我们就把2插入进去,此时maxSum=1+2=3,下一次我们填的数是maxSum+1即4,因为此时前面的数字都能表示,1,2,3都可以用1,2来表示(记得计数加的个数即cnt++)
- 4还是小于5,继续插入4,此时maxSum=3+4=7,填的数字跳到7+1=8(cnt++)
- 因为8大于5,所以5这个数组里数字我们可以加入到最大表示范围中,则maxSum=7+5=12,下一次要填的数是12+1=13(因为5是原数组里的,cnt就不用加了),pos+1
- 此时pos指向10,13是大于10的,所以10也纳入到maxSum中,maxSum=12+10=22>20
至此我们已经找到了最小插入个数,cnt=2,插入的数字是2和4
代码如下:
class Solution {
public:
int minPatches(vector<int>& nums, int n) {
long max_sum=0; //防止超出int类型范围
int m=nums.size();
int cnt=0;
for(long i=1,pos=0;i<=n;){
//当数组里的数用完或者当前要填的数i小于目前pos指针☞的nums[pos]的值,那么就可以插值扩大
if(pos>=m||i<nums[pos]){
cnt++;
max_sum+=i;
}
else{
max_sum+=nums[pos];
pos++;
}
i=max_sum+1;
}
return cnt;
}
};