题目描述: https://leetcode.com/problems/patching-array/description/
问一个数组中需要添加几个数字才能保证数组中的数字任意组合保证可以得到1~n中的任意一个数字的和。
- Naive Solution
从1~n中每个数字挑出来,判断是否可以由数组中的数字组成和,如果不可以则将数字加入数组。其中判断是否可以由数组中的数字组成和可以用递归的方法解决。
class Solution {
private:
bool couldFormNum(int num, vector<int> &nums, int start) {
for (int i = start; i < nums.size(); i++) {
if (nums[i] == num) return true;
if (nums[i] < num && couldFormNum(num - nums[i], nums, i + 1)) return true;
}
return false;
}
public:
int minPatches(vector<int>& nums, int n) {
int orisize = nums.size();
for (int i = 1; i <= n; i++) {
sort(nums.begin(), nums.end());
if (!couldFormNum(i, nums, 0)) {
nums.push_back(i);
}
}
int numsize = nums.size();
return numsize - orisize;
}
};
毫无悬念的TLE了。
所以搜索了大神解法,参考:https://leetcode.com/problems/patching-array/discuss/78488/Solution-+-explanation
总结思路就是我们假设[0,miss)中的值是我们都能组合的,那么当我们要扩张这个范围的,例如miss>1,当我们要扩张到miss的时候,我们是肯定可以做到的,因为我们有数组的组合的和为1的方式。所以基于这种思路,当数组中有小于miss的数例如num,那么我们可以将范围扩大到[0,miss+num),如果没有的话,那我们把miss加入到数组中就可以扩展到[0, 2*miss)了。
题目代码:
class Solution {
public:
int minPatches(vector<int>& nums, int n) {
long miss = 1, added = 0, i = 0;
while (miss <= n) {
if (i < nums.size() && nums[i] <= miss) {
miss += nums[i++];
} else {
miss += miss;
added++;
}
}
return added;
}
};
话说好久不写博客csdn都改版成这个样子了……