其他分享
首页 > 其他分享> > LeetCode - 330. 按要求补齐数组

LeetCode - 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] 区间里所有的数。
所以我们最少需要添加一个数字。
示例 2:

输入: nums = [1,5,10], n = 20
输出: 2
解释: 我们需要添加 [2, 4]。
示例 3:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/patching-array

求解

思路分析

如果当前的数组已经能表示 [1, i-1], 则接下来我们需要表示 i, 而这又分两种情况:
1)如果数组中存在 x <= i,则当然能表示 i,不仅如此,表示的区间扩大到 [1, i+x-1],下一步就需要考虑表示 i+x-1了;
2)如果数组中不存在 x <= i,则只能通过添加一个 i 进入数组(除了新添加一个i外别无它法),如此,表示的区间扩大到 [1, 2*i-1],下一步就需要考虑表示 2*i-1
    class Solution {
    public:
        // 暴力解法
        // 如果当前的数组已经能表示 [1, i-1], 则接下来我们需要表示 i, 而这又分两种情况:
        // 1)如果数组中存在 x <= i,则当然能表示 i,不仅如此,表示的区间扩大到 [1, i+x-1],下一步就需要考虑表示 i+x-1了;
        // 2)如果数组中不存在 x <= i,则只能通过添加一个 i 进入数组(除了新添加一个i外别无它法),如此,表示的区间扩大到 [1, 2*i-1],
        // 则 2) 中就需要考虑表示 2*i-1
        int minPatches(vector<int> &nums, int n) {
            const int LEN = nums.size();
            long long i = 1; // 初始化肯定是需要表示 1
            int index = 0; // 数组下标
            int res = 0; // 记录需要添加的数量
            while (i <= n) {
                if (index < LEN && nums[index] <= i) {
                    // 场景 1), 数组中已存在 x <= i
                    i += nums[index];
                    ++index;
                } else {
                    // 场景 2), 需要将当前表示的 i 添加到数组中
                    ++res;
                    i *= 2;
                }
            }
            return res;
        }
    };

 

标签:数字,nums,int,示例,330,LeetCode,添加,数组,补齐
来源: https://blog.csdn.net/u010323563/article/details/111937006