一、问题
给定一个 已排序 的正整数数组nums,和一个正整数n。从[1, n]区间内选取任意个数字补充到 nums 中 , 使 得 [1,n] 区 间 内 的 任 何 数 字 都 可 以 用 nums 中 某 几 个 数 字 的 和 来 表示。请输出满足上述要求的最少需要补充的数字个数。二、解题思路
三、代码实现
一起来看看代码实现:
#include <iostream>
#include <vector>
int minPatches(std::vector<int>& nums, int n) {
// 累加的总和
long long total = 0;
// 需要补充的数字个数
int count = 0;
// 访问的数组下标索引
int index = 0;
while (total < n) {
if (index < nums.size() && nums[index] <= total + 1) {
// 如果数组能组成的数字范围是[1,total],那么加上nums[index]
// 就变成了[1,total]U[nums[index],total+nums[index]]
// 结果就是[1,total+nums[index]]
total += nums[index++];
} else {
// 添加一个新数字,并且count加1
total = total + (total + 1);
count++;
}
}
return count;
}
int main() {
std::vector<int> nums = {1, 5, 10};
int n = 20;
int result = minPatches(nums, n);
std::cout << "需要补充的数字个数: " << result << std::endl;
return 0;
}
上面组成数字的范围是闭区间,我们还可以改成开区间
[ 1 , total )
,原理都一样,稍作
修改即可,代码如下
#include <iostream>
#include <vector>
int minPatches(std::vector<int>& nums, int n) {
// 累加的总和
long long total = 1;
// 需要补充的数字个数
int count = 0;
// 访问的数组下标索引
int index = 0;
while (total <= n) {
if (index < nums.size() && nums[index] <= total) {
// 如果数组能组成的数字范围是[1,total),那么加上nums[index]
// 就变成了[1,total)U[nums[index],total+nums[index])
// 结果就是[1,total+nums[index])
total += nums[index++];
} else {
// 添加一个新数字,并且count加1
total <<= 1;
count++;
}
}
return count;
}
int main() {
std::vector<int> nums = {1, 5, 10};
int n = 20;
int result = minPatches(nums, n);
std::cout << "需要补充的数字个数: " << result << std::endl;
return 0;
}
标签:std,index,nums,int,long,3.4,total,补齐,贪心
From: https://blog.csdn.net/linshantang/article/details/141670985