【回溯 + 去重】先对元素排序,如果当前元素和前一个元素重复nums[i] == nums[i - 1],并且前一个元素nums[i - 1]没有被用过 !st[i - 1],那就说明前面那个元素是回溯回来的,这时候如果再选用重复的元素 nums[i]就会重复,所以遇到这种情况需要跳过。
class Solution {
List<List<Integer>> ans = new ArrayList();
LinkedList<Integer> list = new LinkedList();
Set<Integer> st = new HashSet();
int[] nums;
int n, target;
void dfs(int t, int sum) {
if (t == n) {
if (sum == target) ans.add(new ArrayList(list));
return;
}
dfs(t + 1, sum);
if (t > 0 && !st.contains(t - 1) && nums[t] == nums[t - 1]) return;
if (sum + nums[t] > target) return;
list.add(nums[t]);
st.add(t);
dfs(t + 1, sum + nums[t]);
list.pollLast();
st.remove(t);
}
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
this.nums = candidates;
this.n = this.nums.length;
this.target = target;
dfs(0, 0);
return ans;
}
}