需求描述:
给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/patching-array
思路:
一开始我的想法是brute-force,对于初始数组,直接穷举所有组合然后求和...时间复杂度可以达到O(n^4)....
使用贪心算法可以最大程度上降低我们算法的复杂度。
核心思路就是设定一个区间,在此区间内的数都是100%已经可以获取的,稳扎稳打!然后用最小的代价不停地扩大这个区间,最终覆盖我们需要的[1,n]。
解答:
from typing import List
class Solution(object):
def minPatches(self, nums: List[int], n: int) -> int:
x=1 #[0,x-1]就是当前可覆盖的范围,从[0,0]开始。
patchNum=0 #需要填补的数的个数
index=0 #目前遍历到数组的第几个元素
leng=len(nums) #数组的长度
#测试的时候可能给一个空数组,要考虑到这个情况!
if leng==0 and index==0:
if n==0: #如果输入的n为0,则返回0
return 0
else: #如果给了一个空的数组,那么我们一定要加入1,此时可以覆盖[0,1],所以x变成2
nums.append(1)
patchNum+=1
x=2
while x<=n:
if index<leng and nums[index]<=x:
x+=nums[index]
index+=1
else:
patchNum+=1
x+=x
return patchNum
nums=[1,3]
n=6
print(Solution().minPatches(nums,n))
复杂度分析
- 时间复杂度:O(N)。只需要一个while循环
- 空间复杂度:O(1)。不需要额外内存