回溯法概念:回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点
出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过
对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来
求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。
概念:http://www.cnblogs.com/jiangchen/p/5393849.html
1. Combination Sum
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:
[
[7],
[2, 2, 3]
]
刚做的时候的思路:
用for循环+ 递归的方式求解
for 循环套在外层,表示遍历数组的第i个数字
内层递归表示结果list里的第i个数字(比如第一层递归是寻找list里的第一个数字)
归纳:其实这就是回溯法做的一个dfs,找到第一个节点,然后再找第二个节点,当固定第一个节点的所有解找到后,再换另外个点做为第一个节点。
1 public class Solution { 2 public List<List<Integer>> combinationSum(int[] candidates, int target) { 3 int size = candidates.length; 4 List<List<Integer>> res = new ArrayList<List<Integer>>(); 5 List<Integer> list = new ArrayList<Integer>(); 6 helper (res, list, candidates, target, 0); 7 return res; 8 } 9 private static void helper(List<List<Integer>> res,List<Integer> list, int[] candidates, int target, int pos) { 10 if (target == 0) { 11 res.add(new ArrayList<Integer>(list)); 12 return; 13 14 } 15 16 if (target < 0) { 17 return; 18 } 19 int prev = -1; 20 for (int i = pos; i < candidates.length; i++) { 21 if(prev == candidates[i]) { 22 continue; 23 } 24 list.add(candidates[i]); 25 helper(res, list, candidates, target - candidates[i], i); 26 prev = candidates[i]; 27 list.remove(list.size() - 1); 28 } 29 } 30 }