leetcode40 (combined sum II: backtracking method)

Given an array of candidates and a target number target, find out all combinations of candidates that can make the sum of the numbers target.
Each number in candidates can only be used once in each combination.

Input: candidates = [10,1,2,7,6,1,5], target = 8,
the solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

Problem solution: The solution of this problem is basically the same as Leetcode39 (combined sum) , except that there will be one more deduplication step. For example, for the array [2,2,3] and target:5, if you follow the normal backtracking method, Using the same solution as Leetcode39 (combined sum) will get two duplicate answers [2,3] and [2,3]. We need to de-duplicate in the backtracking process. The most effective way to de-duplicate is to construct a List The container stores the elements that appear in the array and the number of times the element appears. When we recurse, we no longer recurse the original array, but a constructed List container. An element appears n times, indicating that the element can be recursed 0 to n times. That is, there can be 0 to n times in a solution set array. We only need to use backtracking to enumerate these 0 to n times to get all the results and achieve the purpose of deduplication.

class Solution {
    
    
    private  final Stack<Integer>stack=new Stack<>();
    private  final List<List<Integer>>res=new ArrayList<>();
    private  final List<int[]>arrayElements=new LinkedList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
    
    
        Solution.sort(candidates);
        int repeat=1;
        //构造List容器,存储数组中的元素及其出现次数
        for(int i=0;i< candidates.length-1;i++){
    
    
            if(candidates[i]==candidates[i+1])
                repeat++;
            else{
    
    
                 arrayElements.add(new int[]{
    
    candidates[i],repeat});
                repeat=1;
            }
        }
        arrayElements.add(new int[]{
    
    candidates[candidates.length-1],repeat});
        backTrace(candidates,0,0,target);
        return res;
    }
    private void backTrace(int[]candidates,int pos,int sum,int target){
    
    
          if(sum==target)
              res.add(new ArrayList<>(stack));
          if(pos>=arrayElements.size())
              return;
          int element=arrayElements.get(pos)[0];
          int repeat=arrayElements.get(pos)[1];
          if(target-sum<element)
              return;
          //执行一次循环,则解集数组中出现一次该元素
          for(int i=0;i<repeat;i++){
    
    
              stack.push(element);
              backTrace(candidates,pos+1,sum+element*(i+1),target);
          }
          for(int i=0;i<repeat;i++){
    
    
              stack.pop();
          }
          //结果数组中没有该元素
          backTrace(candidates,pos+1,sum,target);

    }

    //快排算法
    public static void sort(int[]args){
    
    
        quickSort(args,0,args.length-1);
    }
    private static void quickSort(int[]args,int start,int end){
    
    
        if(start>=end)
            return;
        int pivot=args[start];
        int left=start;
        int right=end;
        while(left<right){
    
    
            while(args[right]>pivot&&left<right)
                right--;
            while(args[left]<=pivot&&left<right)
                left++;
            change(args,right,left);
        }
        change(args,start,left);
        quickSort(args,start,left-1);
        quickSort(args,left+1,end);
    }
    private static void change(int[]args,int x,int y){
    
    
        int temp=args[x];
        args[x]=args[y];
        args[y]=temp;
    }

  
}

Guess you like

Origin blog.csdn.net/CY2333333/article/details/108524877