516,贪心算法解按要求补齐数组
Posted 数据结构和算法
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了516,贪心算法解按要求补齐数组相关的知识,希望对你有一定的参考价值。
When the lord closes a door, somewhere he opens a window.
当主关上了一扇门,就会在别处打开一扇窗。
问题描述
给定一个已排序的正整数数组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
贪心算法解决
这题让从数组中找出任意数字都可以组成n,题中说了,数组是排序的。
假设数组中前k个数字能组成的数字范围是[1,total],当我们添加数组中第k+1个数字nums[k](数组的下标是从0开始的)的时候,范围就变成了[1,total]U[nums[k],nums[k]]U[1+nums[k],total+nums[k]],这是个并集,可以合并成[1,total]U[nums[k],total+nums[k]],我们仔细观察一下
1,如果左边的total<nums[k]-1,那么他们中间肯定会有空缺,不能构成完整的[1,total+nums[k]]。
举个例子
[1,5]U[7,10],因为5<7-1,所以是没法构成[1,10]的
这个时候我们需要添加一个数字total+1。先构成一个更大的范围[1,total*2+1]。
这里为什么是添加total+1而不是添加total,我举个例子,比如可以构成的数字范围是[1,5],如果需要添加一个构成更大范围的,我们应该选择6而不是选择5。
2,如果左边的total>=nums[k]-1,那么就可以构成完整的[1,total+nums[k]],就不需要在添加数字了。
来看下代码
1public int minPatches(int[] nums, int n) {
2 //累加的总和
3 long total = 0;
4 //需要补充的数字个数
5 int count = 0;
6 //访问的数组下标索引
7 int index = 0;
8 while (total < n) {
9 if (index < nums.length && nums[index] <= total + 1) {
10 //如果数组能组成的数字范围是[1,total],那么加上nums[index]
11 //就变成了[1,total]U[nums[index],total+nums[index]]
12 //结果就是[1,total+nums[index]]
13 total += nums[index++];
14 } else {
15 //添加一个新数字,并且count加1
16 total = total + (total + 1);
17 count++;
18 }
19 }
20 return count;
21}
另一种写法
上面组成数字的范围是闭区间,我们还可以改成开区间[1,total)
,原理都一样,稍作修改即可,代码如下
1public int minPatches(int[] nums, int n) {
2 //累加的总和
3 long total = 1;
4 //需要补充的数字个数
5 int count = 0;
6 //访问的数组下标索引
7 int index = 0;
8 while (total <= n) {
9 if (index < nums.length && nums[index] <= total) {
10 //如果数组能组成的数字范围是[1,total),那么加上nums[index]
11 //就变成了[1,total)U[nums[index],total+nums[index])
12 //结果就是[1,total+nums[index])
13 total += nums[index++];
14 } else {
15 //添加一个新数字,并且count加1
16 total <<= 1;
17 count++;
18 }
19 }
20 return count;
21}
●
●
●
●
如果觉得有用就点个"赞"吧
以上是关于516,贪心算法解按要求补齐数组的主要内容,如果未能解决你的问题,请参考以下文章