0330. 按要求补齐数组
大约 2 分钟
---
0330. 按要求补齐数组
- 标签:贪心、数组
- 难度:困难
题目链接
题目大意
描述:
给定一个已排序的正整数数组 ,和一个正整数 。从 区间内选取任意个数字补充到 中,使得 区间内的任何数字都可以用 中某几个数字的和来表示。
要求:
请返回「满足上述要求的最少需要补充的数字个数」。
说明:
- 。
- 。
- 按升序排列。
- 。
示例:
- 示例 1:
输入: nums = [1,3], n = 6
输出: 1
解释:
根据 nums 里现有的组合 [1], [3], [1,3],可以得出 1, 3, 4。
现在如果我们将 2 添加到 nums 中, 组合变为: [1], [2], [3], [1,3], [2,3], [1,2,3]。
其和可以表示数字 1, 2, 3, 4, 5, 6,能够覆盖 [1, 6] 区间里所有的数。
所以我们最少需要添加一个数字。- 示例 2:
输入: nums = [1,5,10], n = 20
输出: 2
解释: 我们需要添加 [2,4]。解题思路
思路 1:贪心算法
使用贪心算法来解决这个问题。核心思想是维护一个变量 ,表示当前能够表示的最大连续范围是 。
具体步骤:
- 初始化:设置 ,表示当前能表示的最大连续范围是 ,即空集。
- 遍历数组:
- 如果当前数字 ,说明可以用现有数字表示 范围内的所有数字,更新 。
- 如果当前数字 ,说明存在缺口,需要补充数字 ,然后更新 。
- 处理剩余范围:当数组遍历完后,如果 ,继续补充数字直到能表示 范围内的所有数字。
关键观察:每次补充数字时,选择当前 值是最优的,因为这样可以最大化覆盖范围。
思路 1:代码
class Solution:
def minPatches(self, nums: List[int], n: int) -> int:
patches = 0 # 记录需要补充的数字个数
miss = 1 # 当前能表示的最大连续范围是 [1, miss)
i = 0 # 数组索引
while miss <= n:
# 如果当前数字在可表示范围内,扩展可表示范围
if i < len(nums) and nums[i] <= miss:
miss += nums[i]
i += 1
else:
# 需要补充数字 miss,扩展可表示范围
miss += miss
patches += 1
return patches思路 1:复杂度分析
- 时间复杂度:,其中 是数组 的长度。需要遍历数组一次,然后最多需要 次补充操作。
- 空间复杂度:。只使用了常数额外空间。