Leetcode--Java--330. 按要求补齐数组

题目描述

给定一个已排序的正整数数组 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] 区间里所有的数。
所以我们最少需要添加一个数字。

思路

贪心 + 分类讨论

  1. 考虑当前的数ai和x之间的关系,分类讨论如下:
    在这里插入图片描述
  2. 如果ai小于等于x,数组的数都加上ai以后的范围就是[0, ai + x),这种情况不需要补数,直接用数组里面的数。如果ai大于x的话,直接加上ai会导致中间出现空缺(x没有被表示),所以是直接补上x,让范围变成2x。
  3. 贪心题目思路具有跳跃性,背过即可。
  4. 防止溢出数据范围,用long来表示。
    参考AcWing题解这篇

代码

class Solution {
    
    
    public int minPatches(int[] nums, int n) {
    
    
     long x = 1, res = 0;
     int i = 0;
     //假设[0, x)是已经可以表示的
     while (x <= n) {
    
    
         //如果小于x的话,直接补上数组里面的数nums[i]
         if  (i < nums.length && nums[i] <= x) x += nums[i ++ ];
         else {
    
    
             x += x; //否则补充新的数x,统计结果加一
             res ++;
         }
     }
     return (int)res;
    }
}

猜你喜欢

转载自blog.csdn.net/Sherlock_Obama/article/details/121869017