題目網址:https://leetcode.cn/problems/combination-sum-ii/
題意: 給一 array candidates
和一整數 target
, 求 candidates
中所有可以使數字和為 target
的組合, 且 candidates
中的每個數字在每個組合中只能使用一次 。
注意: Output 不能有重複的組合
Solution 1:
想法:先做 sorting, 再用 DFS, 類似 39. Combination Sum , 一旦不取 nums[j]
, 則後面區間 [j + 1, n)
中若有跟 candidates[j]
相同的都直接跳過
e.g. candidates = [10,1,2,7,6,1,5]
, target = 8
先做 sorting
若不取 idx = 0
的 1
, 則可以直接跳過 idx = 1
的 1
, 讓 idx = 2
的元素開始取
class Solution {public : vector<vector<int >> combinationSum2 (vector<int >& candidates, int target) { sort (candidates.begin (), candidates.end ()); dfs (candidates, 0 , candidates.size (), target); return res; } private : vector<int > cur; vector<vector<int >> res; void dfs (vector<int >& candidates, int i, int n, int target) { if (target == 0 ) { res.emplace_back (cur); return ; } else if (target < 0 || i == n) { return ; } cur.emplace_back (candidates[i]); dfs (candidates, i + 1 , n, target - candidates[i]); cur.pop_back (); while (i + 1 < n && candidates[i] == candidates[i + 1 ]) { ++i; } dfs (candidates, i + 1 , n, target); } };
time: $O(n \cdot 2^n)$ ➔ $O(n \cdot log(n)) + O(n \cdot 2^n)$
$O(n \cdot log(n))$:sorting
$O(n \cdot 2^n)$:最多有 $2^n$ 種組合, 建構每一種組合需 $O(n)$ time
space: $O(n)$ ➔ 若不考慮要返回的 array, 則取決於遞迴的最大深度
Solution 2:
想法:同 Solution 1, 只是透過剪枝(pruning)來做優化, 一旦當前元素超過 target
, 則直接退出(因為有排序)。
class Solution {public : vector<vector<int >> combinationSum2 (vector<int >& candidates, int target) { sort (candidates.begin (), candidates.end ()); dfs (candidates, 0 , candidates.size (), target); return res; } private : vector<int > cur; vector<vector<int >> res; void dfs (vector<int >& candidates, int i, int n, int target) { if (target == 0 ) { res.emplace_back (cur); return ; } for (int j = i; j < n; ++j) { if (candidates[j] > target) { break ; } cur.emplace_back (candidates[j]); dfs (candidates, j + 1 , n, target - candidates[j]); cur.pop_back (); while (j + 1 < n && candidates[j] == candidates[j + 1 ]) { ++j; } } } };
time: $O(n \cdot 2^n)$ ➔ worse case 仍為 $O(n \cdot 2^n)$, 透過使用 pruning, 實際運行情況應該是遠小於 $O(n \cdot 2^n)$ 的
space: $O(target)$ ➔ worse case 下, dfs()
最大遞迴深度為 $O(target)$