2016年12月8日 星期四

[LeetCode] 40. Combination Sum II

轉自LeetCode

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]
]
<Solution>

這題是 Combination Sum 的衍生,一樣要求不重複的排列組合的和

差別在於,每個數字只能用一次

可以基於之前的解法,修改一下來避免重複
  • 為了要避開重複,先 sort
  • 因為每個數字只能用一次,所以每次的 recursive, start = i+1
  • 在 DFS 的 for loop 裡面,增加以下片段來避免重複
if(i > start && candidates[i] == candidates[i-1]) {
    continue;
}


code 如下
c++, O(2^n)
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<vector<int>> ans;
vector<int> out;
//> to avoid duplicate, sort first
sort(candidates.begin(), candidates.end());
//> use DFS to solve
combineByDFS(0, target, candidates, out, ans);
return ans;
}
void combineByDFS(const int &start, const int &target, vector<int> &candidates, vector<int> &out, vector<vector<int>> &ans) {
if(target == 0) {
ans.push_back(out);
}
else {
for(int i = start; i < candidates.size(); i++) {
//> avoid duplicates
if(i > start && candidates[i] == candidates[i-1]) {
continue;
}
else if((target-candidates[i]) >= 0) {
out.push_back(candidates[i]);
//> start = i+1, use each number once
combineByDFS(i+1, target-candidates[i], candidates, out, ans);
out.pop_back();
}
}
}
}
};

kotlin, O(2^n)
class Solution {
private val ans = arrayListOf<List<Int>>()
fun combinationSum2(candidates: IntArray, target: Int): List<List<Int>> {
dfs(0, candidates.sorted(), target, emptyList())
return ans
}
fun dfs(start: Int, candidates: List<Int>, target: Int, cmb: List<Int>) {
if (target == 0) {
ans.add(cmb)
return
}
for(i in start until candidates.size) {
if (i > start && candidates[i] == candidates[i-1]) {
continue
}
if (target - candidates[i] >= 0) {
dfs(i+1, candidates, target - candidates[i], cmb + listOf(candidates[i]))
}
}
}
}

沒有留言:

張貼留言