此题我们仍然考虑用回溯法,其实可以用combination sum I的代码,只需要在递归调用backtracking的时候将startIndex从i变为i+1而已,最后还需要将整个结果集去重(因为存在存在重复数字,假设说我们有三个1,有一种解法需要两个1和其他数字,如果不去重,这一种解法就会膨胀成三个)。
public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); hashset = new HashSet(); LinkedList<Integer> nums = new LinkedList();
backtracking(candidates, target, 0, 0, nums);
res = new ArrayList(hashset); return res; }
privatevoidbacktracking(int[] candidates, int target, int sum, int startIndex, LinkedList<Integer> nums){ for (int i = startIndex; i < candidates.length; i++) { sum += candidates[i]; nums.add(candidates[i]);
if (sum < target) { backtracking(candidates, target, sum, i + 1, nums); nums.removeLast(); sum -= candidates[i]; continue; } elseif (sum == target) { hashset.add(new ArrayList(nums)); }
public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); LinkedList<Integer> nums = new LinkedList(); res = new ArrayList();
backtracking(candidates, target, 0, 0, nums);
return res; }
privatevoidbacktracking(int[] candidates, int target, int sum, int startIndex, LinkedList<Integer> nums){ for (int i = startIndex; i < candidates.length; i++) {
// 优雅的去重方式,记住,以后可能用得到! if (i > startIndex && candidates[i - 1] == candidates[i]) { continue; }
sum += candidates[i]; nums.add(candidates[i]);
if (sum < target) { backtracking(candidates, target, sum, i + 1, nums); nums.removeLast(); sum -= candidates[i]; continue; } elseif (sum == target) { res.add(new ArrayList(nums)); }