package Leetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; //给定一个已排序的正整数数组 nums,和一个正整数 n 。从 [1, n] 区间内选取任意个数字补充到 nums 中, //使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的和来表示。请输出满足上述要求的最少需要补充的数字个数。 public class test330 { public static void main(String[] args) { int []nums={1,5,10}; int n=20; System.out.println(minPatches(nums, n)); } //类似于二进制(1,x-1)补充x后[1,2x]覆盖 public static int minPatches(int[] nums, int n) { int count=0; long x=1; int index=0; while(x<=n){ if(index<nums.length&&nums[index]<=x){ x=x+nums[index]; index++; }else{ x=x*2; count++; } } return count; } //超时了 public static int minPatches1(int[] nums, int n) { int []temp; if(nums.length==0||n==0){ temp=new int[1]; // return 0; }else{ temp=nums.clone(); } List<Integer> list=new ArrayList<>(); helper1(temp, list, new ArrayList<>(), 0,n); Collections.sort(list); int i=1; int count=0; while(list.size()<n){ if(list.contains(i)){ i++; }else{ count++; int x=list.size(); for(int j=0;j<x;j++){ if(!list.contains(list.get(j)+i)&&(list.get(j)+i)<=n){ list.add(list.get(j)+i); } } if(list.contains(0)){ list.remove(0); } if(!list.contains(i)){ list.add(i); } // list.add(i); i=i+1; } } return count; } public static void helper1(int []nums,List<Integer> list,List<Integer> temp,int start,int n){ if(temp.size()!=0){ int sum=0; for(int i=0;i<temp.size();i++){ sum=sum+temp.get(i); } if(!list.contains(sum)&&sum<=n){ list.add(sum); } // list.add(sum); } for(int i=start;i<nums.length;i++){ // if(!temp.contains(nums[i])){ temp.add(nums[i]); helper1(nums, list, temp, start+1,n); temp.remove(temp.size()-1); // } } } }