leetcode40 (suma combinada II: método de retroceso)

Dada una variedad de candidatos y un objetivo de número objetivo, averigüe todas las combinaciones de candidatos que pueden hacer la suma de los números objetivo.
Cada número de candidatos solo se puede usar una vez en cada combinación.

Entrada: candidatos = [10,1,2,7,6,1,5], objetivo = 8,
el conjunto de soluciones es:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

Solución del problema: La solución de este problema es básicamente la misma que la de Leetcode39 (suma combinada) , excepto que habrá un paso más de deduplicación . Por ejemplo, para la matriz [2,2,3] y el objetivo: 5, si sigue el método de retroceso normal, Usando la misma solución que Leetcode39 (suma combinada) obtendrá dos respuestas duplicadas [2,3] y [2,3]. Necesitamos deduplicar en el proceso de retroceso. La forma más efectiva de deduplicar es construir una lista El contenedor almacena los elementos que aparecen en la matriz y la cantidad de veces que aparece. Cuando recurrimos, ya no recurrimos a la matriz original, sino a un contenedor List construido. Un elemento aparece n veces, lo que indica que el elemento se puede repetir de 0 a n veces. Es decir, puede haber de 0 a n veces en una matriz de conjunto de soluciones. Solo necesitamos usar retroceso para enumerar estas 0 a n veces para obtener todos los resultados y lograr el propósito de la deduplicación.

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;
    }

  
}

Supongo que te gusta

Origin blog.csdn.net/CY2333333/article/details/108524877
Recomendado
Clasificación