題目網址:https://leetcode.cn/problems/subsets-ii/

題意:給一 array nums, 當中的元素可能會重複, 返回所有可能的 subset res

注意:res 不能包含重複的 subset, 可以按順序任意排列

Solution:

想法:利用 DFS, 先將 nums 排序(讓相同值的數相鄰), 然後跟 78. Subsets 一樣

  • 不一樣的是, res 中不能有重複的 subset
  • 只是若不取, 則後面跟當前值一樣的數, 都要跳過, 從值不一樣的繼續

e.g. nums = [1, 2, 2, 3]
下圖中紅色圈起來的部分, 即是選 1 之後不選 2, 所以後面值為 2 的都要跳過, 下一個從 3 開始取

class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
dfs(nums, 0, nums.size());
return res;
}

private:
vector<int> cur;
vector<vector<int>> res;

void dfs(vector<int>& nums, int i, int n){
if (i == n) {
res.emplace_back(cur);
return;
}

// 取
cur.emplace_back(nums[i]);
dfs(nums, i + 1, n);
cur.pop_back();

// 不取
while (i + 1 < n && nums[i] == nums[i + 1]) {
++i;
}

dfs(nums, i + 1, n);
}
};
  • 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$ 種 subset, 建每一種 subset 需 $O(n)$ time
  • space:$O(n)$ ➔ 若不考慮要返回的 array, 則取決於遞迴的最大深度