题目描述

给定一个已排序的正整数数组 nums ,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。

示例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]。

示例3

        输入:
nums = [1,2,2], n = 5
输出:
0

题解

首先这题没有说数据范围,根据正解的时间复杂度,推测出 nums.length 的大小在 1e5 左右,而 n 的大小在 int 的最大值左右。

而不考虑数据范围,我刚开始的想法是,首先考虑简化问题:用 nums 数组中的数字可以表示出多少个不同的正整数? 这可以用动态规划来解决,令 dp[S][i] 表示用前 i 个数凑出和 S 是否可行,那么状态转移方程就是: dp[S][i] = dp[S-nums[i]][i-1] || dp[S][i-1] 。 然后遍历 dp[i][nums.length-1] ,如果发现等于 0 ,就说明 nums 数组无法凑出 i 这个和,于是新增加一个数 i ,并且将 [i, 2i)中的所有 dp 值都改成 1,直到 [1, n] 全部被覆盖了。 后来看了才发现,我弱智了,这样不仅没必要,而且 n 太大会炸裂。

正解很简单。首先题目中有个词“已排序”,其实不是很重要,没排序的话我排个序也不怎么耗时间。那排完序怎么办呢,思路还是刚刚的思路,只是不用动态规划了。

试想从最小的 1 开始,如果 1 不在数组里,那一定要补上一个 1 的,然后 [1, 2) 范围里的数都可以被表示出来了。然后看下一个数,如果大于 2 ,那么 2 是没有办法通过数组里的数表示出来的,因为比它小的数只能凑出 [1, 2) ,所以 2 也要补上。如果下一个数小于等于 2 ,那么我们可以利用目前的数凑出 [1, 4) 里面的数,然后继续往下遍历,直到能够凑出 [1, n+1) 里面的数。

一般情况下,如果遍历到 nums[i-1] 时,可以表示出 [1, S) 范围内的数,那么如果 nums[i] > S ,那么需要补上 S ,并且可表示范围更新为 [1, 2S),然后继续看 nums[i] ;否则的话可表示范围更新为 [1, S+nums[i]) ,然后看 nums[i+1] 就行了。

这样就比原来的思路简化了很多了,那么时间复杂度怎么样呢? 因为 S 每次更新有两种情况,要么乘以 2 ,要么加上了 nums[i] ,所以最终时间复杂度是

代码

c++

        class Solution {public:int minPatches(vector<int>& nums, int n) {int len = nums.size(), idx = 0, res = 0;long long r = 1;while (r <= n) {if (idx < len && nums[idx] <= r) {r += nums[idx++];} else {res++;r += r;}}return res;}
};

python

        class Solution:def minPatches(self, nums: List[int], n: int) -> int:length = len(nums)idx = res = 0r = 1while r <= n:if idx < length and nums[idx] <= r:r += nums[idx]idx += 1else:res += 1r += rreturn res

每日算法系列【LeetCode 330】按要求补齐数组相关推荐

  1. Java实现 LeetCode 330 按要求补齐数组

    330. 按要求补齐数组 给定一个已排序的正整数数组 nums,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums ...

  2. leetcode 330. 按要求补齐数组(贪心算法)

    给定一个已排序的正整数数组 nums,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示.请 ...

  3. LeetCode 330. 按要求补齐数组(贪心)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个已排序的正整数数组 nums,和一个正整数 n . 从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数 ...

  4. 330. 按要求补齐数组

    给定一个已排序的正整数数组 nums,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示.请 ...

  5. 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符

    题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...

  6. 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 330】按要求补齐数组...

    题目描述 给定一个已排序的正整数数组 nums ,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的 ...

  7. 求栈中元素个数算法_每日算法系列【LeetCode 315】计算右侧小于当前元素的个数...

    题目描述 给定一个整数数组 nums ,按要求返回一个新数组 counts .数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量. 示例 ...

  8. 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和

    题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...

  9. 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 523】连续的子数组和...

    题目描述 给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数. 示例1 输入: [ ...

  10. 序列复杂度怎么看_每日算法系列【LeetCode 376】摆动序列

    题目描述 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个 ...

最新文章

  1. 青源 LIVE 预告 | 北大王一飞:高效 GAN 采样算法 (ECML 最佳论文解读)
  2. 如何汉化DNN--中文语言包的使用
  3. python人脸识别毕业设计-Python 40行代码实现人脸识别功能
  4. 【Elasticsearch】es 使用Rollup在Elasticsearch 6.3中合并旧日志 上卷 Rollup
  5. panoramic image view 全景照片查看器
  6. Mimics17.0安装教程
  7. ISO 3166-1标准国家代码表
  8. 正面管教读书笔记 02 几个基本概念
  9. 虚拟服务器vdi重删,VDI桌面虚拟化简介
  10. 在Excel中将人民币金额小写转成大写(转)
  11. 股票融资融券通俗理解及利率
  12. Solidworks设计电路外形导入AltiumDesigner
  13. 语音-小度自定义技能
  14. Windows 7 SP1补丁包 (32位) V 2013.10 官方版
  15. 杭州程序员从互联网跳央企,晒一天工作和收入,网友:待一年就废
  16. 前端vue项目(使用pdf.js) pdf展示及pdf工具栏放大缩小功能实现
  17. python爬虫系列:xpath爬取图片讲解(零基础向)
  18. U盘杀毒软件U盘Clear
  19. 单词2016.8.3
  20. 【私人备忘录】Android P 去电代码流程

热门文章

  1. c++冒泡排序的类模板的实现
  2. C++多态的练习——编写一个计算器项目
  3. 20165222第三周作业
  4. 2. Linear Model
  5. C++编程语言中类对象的赋值与复制介绍(三)
  6. 站闻资讯项目开发个人总结
  7. Atitit java集成内嵌浏览器与外嵌浏览器attilax总结
  8. Http下的各种操作类.WebApi系列~通过HttpClient来调用Web Api接口
  9. 接口与继承:不允许继承的类
  10. javascript:typeof与instanceof区别