330. 按要求补齐数组
时间:2020年12月29日
知识点:贪心、模拟
题目链接:https://leetcode-cn.com/problems/patching-array/
题目
给定一个已排序的正整数数组 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
解法:
- 在这里我们需要明白什么时候需要加一个数字,经过自己简单模拟可以发现
- 当数组中数字可以覆盖到[1,x-1]时 也就是数组中的和为x-1时 想要继续覆盖x 需要添加数字x是最好的,可以使覆盖范围到达[1,2x-1]
- 如[1,2,4]这个数组最多能覆盖7 想要覆盖到 8 可以添加8、7、6、4等 但是添加了8 能够保证添加后 最大的覆盖范围为15
- 这样就有初步的思路 一个标记能够覆盖的范围 一个标记数组的下标
- 如果下标对应的数字 <= 能够覆盖的范围 扩大能够覆盖的范围 如[1,2,3] 最大为6
- 如果对应的数字 > 能够覆盖的范围 相当于有空档 如[1,2,7] 当遍历到2时 最大的是3 3和7之间有空档 此时添加4 就可以到达7 最后到达14
代码
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int minPatches(vector<int>& nums, int n) {
int ans = 0;
long long cover = 0;
int index = 0;
while(1){
if(cover >= n)
break;
// 需要注意的是如何处理连续的数组 如[1,2,3]
if(index < nums.size() && nums[index] <= cover+1){
cover += nums[index];
index++;
}else{
cover = 2*cover +1;
ans++;
}
}
return ans;
}
};
int main()
{
Solution s;
vector<int> nums{1,2,2};
int n = 5;
cout<<s.minPatches(nums, n)<<endl;
return 0;
}
今天也是爱zz的一天哦!