第40题:组合总和II

一、问题描述:

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]
二、思路
总体采用先递归回溯找到所有的可能值,然后进行去重处理
1.在递归过程中,对递归函数的构建(全局变量list存储可能值,nowData值存储某一个对象中的一系列值,number记录下一步需要添加的值,candidates数组,target目标值);
2.在递归函数中,我的思路是首先判断存储的nowData值是否符合目标值,如果符合则添加到全局变量中,如果不符合,再判断是否小于目标值。
3.小于目标值则继续添加下一个数字进行递归。
4.大于目标值则直接结束该递归函数
5.对于去重,直接使用set表进行去重,因为set表进行去重
三、代码
     public List<List<Integer>> combinationSum2(int[] candidates, int target) {
         List<List<Integer>> temp=new ArrayList<List<Integer>>();
         Arrays.sort(candidates);
         for(int q=0;q<candidates.length;q++)
         {
           FindAll(temp, String.valueOf(candidates[q]), q+1, candidates, target);
         }
         
         //利用set去重
         Set<List<Integer>> alltemp=new HashSet<List<Integer>>();
         
         alltemp.addAll(temp);
         
         temp.clear();
         temp.addAll(alltemp);
         return temp;     
        }
     
     
     
     //使用回溯算法
     public void FindAll( List<List<Integer>> temp,String nowData,int number,int[]candidates,int target)
     {
        
        String [] nd=nowData.split(",");
        int com=0;
        for(int i=0;i<nd.length;i++)
         {
             com=Integer.parseInt(nd[i])+com;             
         }
        
        if(com==target)
        {
             //将记录的值转换为int类型并保存至数组中
             List<Integer> smalltemp=new ArrayList<Integer>();
             for(int j=0;j<nd.length;j++)
             {        
                 smalltemp.add(Integer.parseInt(nd[j]));
                 
             }
             temp.add(smalltemp);    
        } 
        else if(com>target)
        {
            return;            
        }
        else
        {
            if(number>=candidates.length)
            {
                return;
            }
            else
            {
                for(int i=number;i<candidates.length;i++)
                {
                    FindAll(temp, nowData+","+candidates[i], i+1, candidates, target);
                }
                                
            }            
            
        }  
     }


原文地址:https://www.cnblogs.com/xiaobaidashu/p/10792321.html