leetcode Patching Array

题目链接
这个题说实话我没做上。有点难度。
这道题给我们一个有序的正数数组nums,又给了我们一个正整数n,问我们最少需要给nums加几个数字,使其能组成[1,n]之间的所有数字,注意数组中的元素不能重复使用,否则的话只有要有1,就能组成所有的数字了。这道题我又不会了,上网看到了史蒂芬大神的解法,膜拜啊,这里就全部按他的解法来讲吧。我们定义一个变量miss,用来表示[0,n]之间最小的不能表示的值,那么初始化为1,为啥不为0呢,因为n=0没啥意义,直接返回0了。那么此时我们能表示的范围是[0, miss),表示此时我们能表示0到miss-1的数,如果此时的num <= miss,那么我们可以把我们能表示数的范围扩大到[0, miss+num),如果num>miss,那么此时我们需要添加一个数,为了能最大限度的增加表示数范围,我们加上miss它本身,以此类推直至遍历完整个数组,我们可以得到结果。下面我们来举个例子说明:

给定nums = [1, 2, 4, 11, 30], n = 50,我们需要让[0, 50]之间所有的数字都能被nums中的数字之和表示出来。

首先使用1, 2, 4可能表示出0到7之间的所有数,表示范围为[0, 8),但我们不能表示8,因为下一个数字11太大了,所以我们要在数组里加上一个8,此时能表示的范围是[0, 16),那么我们需要插入16吗,答案是不需要,因为我们数组有1和4,可以组成5,而下一个数字11,加一起能组成16,所以有了数组中的11,我们此时能表示的范围扩大到[0, 27),但我们没法表示27,因为30太大了,所以此时我们给数组中加入一个27,那么现在能表示的范围是[0, 54),应经满足要求了,我们总共添加了两个数8和27,所以返回2即可。
这个是标准答案

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

而我写的代码则是这样的,没有理解算法的真谛,把数字居然一个一个找出来了。

import java.util.Arrays;

public class Solution {
    public static void main(String args[])
    {
        Solution solution=new Solution();
        System.out.println(solution.minPatches(new int[]{1,2,31,33}, 2147483647));
        ;
    }

    public int minPatches(int[] nums, int n) {

        int count=0;
        int index=-1;
        int target=1;
        int len=nums.length;
        while(target<n)
        {
            if(!findNumber(nums, index, target))
            {

                if(index+1>=len||nums[index+1]>target)
                {
                    nums=Arrays.copyOf(nums, nums.length+1);
                    nums[nums.length-1]=target;
                    Arrays.sort(nums);
                    target=2*target-1;
                    index++;
                    count++;
                    continue;
                }
                else
                {
                    while(index+1<len&&nums[index+1]<target)
                    {
                        index++;
                    }
                    index++;
                    target+=nums[index];
                }



            }
            else
            {
                target++;
            }
        }
        return count;
    }

    public boolean findNumber(int[] nums,int end,int target)
    {
        if(end>=nums.length)
        {
            return false;
        }
        int diff=target;
        while(end>=0&&diff>0)
        {

            if(nums[end]<=diff)
            {
                diff-=nums[end];
            }
            end--;

        }
        return diff==0;
    }
}

你可能感兴趣的:(leetcode Patching Array)