题目:
给定一个已排序的正整数数组 nums , 和一个正整数 n 。 从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。
请返回 满足上述要求的最少需要补充的数字个数 。
算法:
怎么找到这个规律啊!
方法一:数学
func minPatches(nums []int, n int) int {
numMax := 1
count := 0
index := 0
length := len(nums)
for numMax <= n {
if index >= length || nums[index] > numMax {
count ++
numMax = numMax * 2
} else {
numMax = numMax + nums[index]
index ++
}
}
return count
}
假设当前能表达的范围为[1,numMax],新进来一个nums[i],则表示的范围为:
[1,numMax] U [nums[i]] U [1 + nums[i], numMax + nums[i]]
即[1,numMax] U [nums[i], numMax + nums[i]]
分类讨论:
- 如果numMax < nums[i] - 1,则必须新加一个数nums[i] - 1,表达范围变成[1, nums[i] + nums[i] + 1].
- 如果numMax >= nums[i] - 1,则不用新加数,表达范围变成[1,numMax + nums[i]]
func minPatches(nums []int, n int) int {
numMax := 0
count := 0
index := 0
length := len(nums)
for numMax < n {
if index < length && nums[index] <= numMax + 1{
numMax = numMax + nums[index]
index ++
} else {
count ++
numMax = numMax * 2 + 1
}
}
return count
}