思路:在包含問題的解空間中,按照深度優先搜索的策略,從根節點出發深度探索解空間樹,當探索到某一節點時,先判斷該節點是否包含問題的解,若是包含,就從該節點觸發繼續探索下去,若是不包含該節點的解,則逐層向其祖先節點回溯。html
組合總和:給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中全部能夠使數字和爲 target 的組合。數組
candidates 中的數字能夠無限制重複被選取。bash
說明: 全部數字(包括 target)都是正整數。 解集不能包含重複的組合。post
假設輸入數據爲 candidates = [2,3,5], target = 8
。能夠作以下初步分析:ui
參照回溯法的思路:按照深度優先的規則,這裏對「深度」的定義則是從第一元素開始,由於它能夠被無限制的選取,那麼就能夠一直累加知道它會超過目標值,而後進行回溯spa
去掉了超過目標值的節點code
到新的頭節點以後,繼續遵循深度優先的原則便可cdn
public List<List<Integer>> combinationSum(int[] candidates, int target) {
//先排序,方便直接拋棄大的值
Arrays.sort(candidates);
//開始深度搜索,從圖中第一個位置開始找
List<List<Integer>> rs = dst(0,target,candidates);
return rs;
}
public List<List<Integer>> dst(int start,int target,int[] candidates){
List<List<Integer>> rs = new ArrayList<>();
for(int i=start;i<candidates.length;i++){
int v=candidates[i];
if(v>target){
break;//不知足條件,結束探索
}else if(v==target){
//恰好知足解的條件,加入解集
rs.add(Arrays.asList(v));
} else{
//深度優先探索
List<List<Integer>> sc= dst(i,target-v,candidates);
for(List<Integer> s:sc){
//組合後續的結果
List<Integer> f = new ArrayList<>();
f.add(v);
f.addAll(s);
rs.add(f);
}
}
}
return rs;
}
複製代碼
回溯思路總結htm