必要に応じて配列を埋めますjava

正の整数numsと正の整数nのソートされた配列が与えられます。区間[1、n]から任意の数を選択し、それをnumsに追加します。これにより、区間[1、n]内の任意の数を、numsの特定の数の合計で表すことができます。上記の要件を満たす最小桁数を出力してください。

例1:

入力:nums = [1,3]、n = 6
出力:1
説明:
既存の組み合わせ[1]、[3]、[1,3]によると、nums、1、3、4を取得できます。
ここで、numsに2を加算すると、組み合わせは[1]、[2]、[3]、[1,3]、[2,3]、[1,2,3]になります。
合計は、1、2、3、4、5、6の数値を表すことができ、区間[1、6]のすべての数値をカバーできます。
したがって、少なくとも1つの番号を追加する必要があります。
例2:

入力:nums = [1,5,10]、n = 20
出力:2
説明:[2、4]を追加する必要があります。
例3:

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

出典:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/patching-array
著作権はLeetCodeが所有しています商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。

アイデア:このような質問については、数人の解決策を読み、理解して統合し、最も適切な書き方を選択することができます

class Solution {
    
    
    public int minPatches(int[] nums, int n) {
    
    
         //评论区大佬太牛了,他的原评论粘贴一下
        //  可以这么理解,以[1,5,10]的例子为例: 我们从1开始遍历,并且维护一个指向nums的下标.一开始是1,而          我们看到当前nums数组的第一个元素就是1,所以不需要其他操作.直接跳到2,并且让pos指向nums的第二个元素;

        //  现在,我们的目标数是2,但是当前pos指向的数却是5,显然我们只能自己填充一个2,所以让res+1;既然我们已经填过2了,而在2之前可以被覆盖的最长区间长度是1,所以当前可以遍历到的最大区间长度变成了3(即2 + 1);

        //  然后,我们可以忽略3,直接跳到4(因为上一步已经知道3在最大覆盖范围内了)。我们发现4同样比当前pos所指向的nums元素小,所以我们得填入4,即让res+1;既然已经填入4了,而我们知道在4之前可以覆盖的连续区间是(1-3),所以当前可以覆盖的最大区间被扩展到了7(即4 + 3)。

        //  接下来我们可以直接跳过5、6、7来到8,而当前pos所指向的元素是5,所以当前可覆盖的区间大小又可以加上5了(7+5 = 12),并让pos指向下一个元素

        //  最后我们跳过了7-12,从13开始遍历,这时候pos所指的元素是10,所以覆盖范围变成了12 + 10 = 22 >20,说明可以完全覆盖指定区间了!

        //  到这里大概能够看出端倪 :我们不断维持一个从1开始的可以被完全覆盖的区间,举个例子,当前可以完全覆盖区间是[1,k],而当前pos所指向的nums中的元素为B,说明在B之前(因为是升序,所以都比B小)的所有元素之和可以映射到1-----k,而当我们把B也加入进去后,显然,可映射范围一定向右扩展了B个,也就是变成了1---k+B,这就是解题的思路
        //因为他的不是java的,所以就不贴他的了
        //这是另一个人的,不过理解还是上面的注释理解就行了,先看懂题目
        long range = 0; 
        int idx = 0, res = 0, len = nums.length;
        //arc就是range,我自己打了一遍
        while (range < n) {
    
    
            //判断num与目标值ach + 1的大小关系,如果num > ach + 1,则说明[ach + 1, num - 1]区间内的数字无法表示,必须补充插入新数。为了使插入的新数既能表示ach + 1,又能尽可能覆盖更多的数组(贪心的关键之处),插入的数字就是ach + 1,更新ach = ach + ach + 1
            if (idx >= len || range + 1 < nums[idx]) {
    
    
                res++;
                range += range + 1;
            } else {
    
    //如果num < ach + 1,说明当前的目标值ach + 1必然可以实现(因为num >= 1),此时更新ach = ach + num
                range += nums[idx];
                idx++;
            }
        }
        return res;
    }
}

おすすめ

転載: blog.csdn.net/weixin_43824233/article/details/111911195