首页 > 代码库 > [LeetCode]Patching Array
[LeetCode]Patching Array
题目:Patching Array
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
.
题目:
给定一个递增数组和正整数n,找到最少的缺失的数字,使得使用递增数组中的数字和它们的和能包含[1,n]中的所有数字。
思路:
看似复杂实际上很简单,只要能够发现,任何数字int型数字可以使用32位二进制表示,如果在递增的数组中包含所有的二进制的位数对应的数(1,2,4,8,16,...,1024,...)就必然能表示出[1,n]中的所有数字。
进一步我们可以发现当有这样的情况发生时,则必然需要补充数字:
当前k个数的和小于第k+1个数时,其前k个数的和 + 1的数字必须要补充,类似二进制中进位的思想。
这样实际上只需要不停地求前n项和,在和下一个数字比较就能知道那些数字需要补充。
/** 在[1,n]之间的任何一个数i的二进制形式是由01组成,所以可以使用1,2,4,...的和来组成i; 因此,只需要判断数组中的元素有没有1,2,4,...或能组成上面这些数的数组合。 **/ int LeetCode::minPatches(vector<int>& nums, int n){ long long m = 1; int i = 0, patch = 0;//统计patch的数量 while (m <= n){ if (i < nums.size() && nums[i] <= m){ m += nums[i++];//如果nums[i] == m时,m翻倍;反之m会增加nums[i]的大小;经验可知,只要有1,2以及(n,2n)之间的数k可以得到2n。 } else{//m在nums中不存在,或者数组的数值不够 m <<= 1; ++patch; } } return patch; }
其中,注意
m <<= 1;
补充了元素之后前n项和还要加上补充的元素的值。这里之间变成两倍。
[LeetCode]Patching Array