题目地址
https://leetcode-cn.com/problems/combination-sum-ii/
题目描述
Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sum to target.
Each number in candidates may only be used once in the combination.
Note: The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8
Output:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5
Output:
[
[1,2,2],
[5]
]
Constraints:
- 1 <= candidates.length <= 100
- 1 <= candidates[i] <= 50
- 1 <= target <= 30
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
跟39题类似,但是本题要求每个数字只能使用一次,所以在39题的代码基础上修改一下就可以了。
39题见:https://blog.csdn.net/qq_31650113/article/details/112613283
但是由于本题的数组candidates中存在重复元素,这导致在回溯过程中出现重复答案的情况,比如example 1里的答案是:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
如果直接回溯的话,答案是:
[
[1,1,6],
[1,2,5],
[1,7],
[1,2,5],//重复
[1,7],//重复
[2,6]
]
会有两个重复的答案
所以,借助hashset的特点,去除了重复元素。
当然,本题也可以通过改进递归回溯过程实现去重,这里是比较简单的一种方法。
题解
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> lists = new ArrayList<>();
List<Integer> list = new ArrayList<Integer>();
Arrays.sort(candidates);
findCombination(candidates,target,lists,list,0);
HashSet h = new HashSet(lists);
lists.clear();
lists.addAll(h);
return lists;
}
public void findCombination(int[] candidates,int target,List<List<Integer>> lists,List<Integer> list,int index){
if(target<=0){
if(target==0)
lists.add(new ArrayList<Integer>(list));
return;
}
if(index==candidates.length) return;
target -= candidates[index];
list.add(candidates[index]);
findCombination(candidates,target,lists,list,index+1);
target += candidates[index];
list.remove(list.size()-1);
findCombination(candidates,target,lists,list,index+1);
}
}