10、组合总和(面试题可能会出现)

题目描述
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
首先这道题拿到我就猜到是回溯法,首先肯定要对数组进行排序一下,然后以
[2,3,5], target = 8为例子,首先是2,我们发现8-2=6>0继续-2=4>0 继续-2=2>0继续-2=0好的,我们把产生的这个临时list放入最后的list,然后弹出最后放入的2,目前是2,然后放入3 = -1<0 好的,继续弹出2,然后=4放入3=1>0放入5<0弹出5,弹出3弹出2,弹出2,然后以此到3,放入三个3后为9>8,因此需要弹出一个三,…之后就是3,5,递归和回溯需要注意的是临时的list就一个,因此当不满足条件时需要弹出,因此每次调用之后都需要弹出
代码(对回溯和递归还是不太熟悉,需要注意啊)

public List<List<Integer>> combinationSum(int[] candidates, int target) {
		  Arrays.sort(candidates);
		        List<Integer> list = new ArrayList<>();//新建堆栈用来判断
		        List<List<Integer>> res = new ArrayList<>();//结果集
		        if (candidates == null || candidates.length == 0)
		            return res;
		        combin(candidates, 0, target, list, res);
		        return res;
		    }
		    //对数组元素(已排序)进行逐个判断以及加入结果集
     private void combin(int[] candidates, int start, int target,List<Integer> list, List<List<Integer>> res) {
		        //刚好满足则将结果存入结果集
		        if (target == 0) {
		            res.add(new ArrayList<>(list));
		            return;
		        }
		        for (int i = start; i < candidates.length; i ++) {
		            if (candidates[i] <= target) { //判断是否已经大于target
		                list.add(candidates[i]);//将第一个元素存入         
		                combin(candidates, i, target -candidates[i] , list, res);//继续判断进栈元素
		                list.remove(list.size() - 1);//不满足则将最后一个元素移除,进栈新元素判断
		            }
		        }      
		    }
	

排名靠前的代码

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

class Solution {
    private void search(int[] candidates, int target, int[] count, List<List<Integer>> res, int n) {
        if(target == 0) {
            List<Integer> list = new ArrayList<Integer>();
            for(int i = 0; i <= n; i++) {
                for(int j = 0; j < count[i]; j++) {
                    list.add(candidates[i]);
                }
            }
            res.add(list);
        }
        
        if(n == candidates.length || target < candidates[n])
            return;
        
        search(candidates, target, count, res, n + 1);
        count[n]++;        
        search(candidates, target - candidates[n], count, res, n);
        count[n]--;
    }
    
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        if(candidates == null || candidates.length == 0) {
            return new ArrayList<List<Integer>>();
        }
        
        Arrays.sort(candidates);
        
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        int[] count = new int[candidates.length];
        search(candidates, target, count, res, 0);
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34446716/article/details/86369476
今日推荐