思路和leetcode39 combination sum 很是相似,只是這裏須要增長進行重複處理的部分。請參考我對leetcode39進行解答的這篇博客。面試
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
題目中新添的要求包括數組中存在重複值,並且數組中每一個值只能夠使用一次。segmentfault
這題與leetcode39的思路基本相同,利用遞歸的方法記錄前一次狀況做爲下一次的初始狀況。須要注意的是,既然數組中存在重複的值,就要注意可能會將重複的狀況加入結果數組。
例如,若是數組爲[2,2,2,6],目標值爲8,可能會在結果數組中出現屢次[2,6]
一樣的,在進行遞歸的子遍歷的時候也要注意,可能會出現重複值,例如數組爲[2,2,2,6],目標值爲10,則結果集[2,2,6]也可能出現屢次,因此在子遍歷中也要記得去除重複狀況。
代碼以下數組
public class CombinationSum2_40 { List<List<Integer>> result = new ArrayList<List<Integer>>(); public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); int length = candidates.length; for(int i = 0 ; i<length ; i++){ //去除外圍重複狀況 if(i>0 && candidates[i] == candidates[i-1]){continue;} if(candidates[i] == target){ result.add(Arrays.asList(candidates[i])); }else{ List<Integer> temp = new ArrayList<Integer>(); temp.add(candidates[i]); combinationSum2(candidates, target-candidates[i], i+1, temp); } } return result; } public void combinationSum2(int[] candidates, int target, int startAt, List<Integer> currentList){ for(int i = startAt ; i<candidates.length ; i++){ if(candidates[i] == target){ currentList.add(candidates[i]); result.add(currentList); return; } if(candidates[i] > target){ return; } if(candidates[i] < target){ List<Integer> temp = new ArrayList<Integer>(currentList); temp.add(candidates[i]); combinationSum2(candidates, target-candidates[i], i+1, temp); } //去除自遍歷中的重複狀況 while(i<candidates.length-1 && candidates[i] == candidates[i+1]){i++;} } } }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~微信