Given a sorted positive integer array nums and an integer n, add/patch elements to the array such that any number in range [1, n]
inclusive can be formed by the sum of some elements in the array. Return the minimum number of patches required.
Example 1:
nums = [1, 3]
, n = 6
Return 1
.
Combinations of nums are [1], [3], [1,3]
, which form possible sums of: 1, 3, 4
.
Now if we add/patch 2
to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3]
.
Possible sums are 1, 2, 3, 4, 5, 6
, which now covers the range [1, 6]
.
So we only need 1
patch.
Example 2:
nums = [1, 5, 10]
, n = 20
Return 2
.
The two patches can be [2, 4]
.
Example 3:
nums = [1, 2, 2]
, n = 5
Return 0
.
题意
告诉你几个元素组成的数组nums[ ]和表示范围n,问最少向数组中添加多少元素使得从nums[ ]中若干元素之和能够覆盖[1..n]
思路
假设数组nums的“部分元素和”可以表示范围[1, total)内的所有数字,
那么向nums中添加元素add可以将表示范围扩充至[1, total + add),其中add ≤ total,当且仅当add = total时取到范围上界[1, 2 * total)
若nums数组为空,则构造[1, n]的nums为[1, 2, 4, 8, ..., k],k为小于等于n的2的幂的最大值。
cur表示当前能表示的范围为[1..cur],扫描nums[ ],贪心原则如下:
若nums[i]<=2*cur + 1,把nums[i]添加进来,表示范围更新[1..cur+nums[i]];
若nums[i]>2*cur + 1,添加新的元素cur+1,表示范围更新[1..2*cur+1].
cur从0开始
注意
cur可能溢出
- class Solution {
- public:
- int minPatches(vector<int>& nums, int n) {
- long long cur = 0;
- int i = 0,add = 0;
- while(cur<n){
- if(i < nums.size()&&nums[i] <= cur + 1) {
- cur +=nums[i];
- i ++ ;
- }
- else {
- add++;
- cur = 2*cur + 1;
- }
- }
- return add;
- }
- };