cpp
class Solution {
public:
vector<int> res; // 当前子集
vector<vector<int>> result; // 存储所有子集
void backtracing(vector<int>& nums, int index, vector<bool>& used) {
result.push_back(res); // 将当前子集加入结果
for (int i = index; i < nums.size(); i++) {
// 跳过重复元素
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1]==false) {
continue;
}
res.push_back(nums[i]); // 将当前元素加入子集
used[i] = true; // 标记当前元素已使用
backtracing(nums, i + 1, used); // 递归生成后续子集
used[i] = false; // 取消标记,回溯
res.pop_back(); // 从子集中移除当前元素,回溯
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<bool> used(nums.size(), false); // 标记数组元素是否被使用
sort(nums.begin(), nums.end()); // 排序数组以便于去重
backtracing(nums, 0, used); // 调用回溯函数开始生成子集
return result; // 返回所有生成的子集
}
};
主函数调用
subsetsWithDup
函数 :- 输入
nums = {1, 2, 2}
- 初始化
used = {false, false, false}
- 对
nums
进行排序(尽管已经排好序了),结果nums = {1, 2, 2}
- 调用
backtracing(nums, 0, used)
- 输入
回溯函数执行
-
第一次调用
backtracing(nums, 0, used)
:index = 0
- 当前子集
res = {}
- 当前结果
result = {``{}}
循环1(i = 0):
nums[0] = 1
未使用res.push_back(1)
->res = {1}
used[0] = true
- 调用
backtracing(nums, 1, used)
-
第二次调用
backtracing(nums, 1, used)
:index = 1
- 当前子集
res = {1}
- 当前结果
result = {``{}, {1}}
循环1(i = 1):
nums[1] = 2
未使用res.push_back(2)
->res = {1, 2}
used[1] = true
- 调用
backtracing(nums, 2, used)
-
第三次调用
backtracing(nums, 2, used)
:index = 2
- 当前子集
res = {1, 2}
- 当前结果
result = {``{}, {1}, {1, 2}}
循环1(i = 2):
nums[2] = 2
未使用res.push_back(2)
->res = {1, 2, 2}
used[2] = true
- 调用
backtracing(nums, 3, used)
-
第四次调用
backtracing(nums, 3, used)
:index = 3
- 当前子集
res = {1, 2, 2}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}}
- 结束条件
index >= nums.size()
达成,返回上一层
回溯:
res.pop_back()
->res = {1, 2}
used[2] = false
- 返回上一层
-
回到第三次调用
backtracing(nums, 2, used)
:- 当前子集
res = {1, 2}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}}
回溯:
res.pop_back()
->res = {1}
used[1] = false
循环2(i = 2):
nums[2] = 2
未使用,且nums[2] == nums[1]
,但used[1] == false
,跳过- 返回上一层
- 当前子集
-
回到第二次调用
backtracing(nums, 1, used)
:- 当前子集
res = {1}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}}
回溯:
res.pop_back()
->res = {}
used[0] = false
循环2(i = 1):
nums[1] = 2
未使用res.push_back(2)
->res = {2}
used[1] = true
- 调用
backtracing(nums, 2, used)
- 当前子集
-
第五次调用
backtracing(nums, 2, used)
:index = 2
- 当前子集
res = {2}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}, {2}}
循环1(i = 2):
nums[2] = 2
未使用res.push_back(2)
->res = {2, 2}
used[2] = true
- 调用
backtracing(nums, 3, used)
-
第六次调用
backtracing(nums, 3, used)
:index = 3
- 当前子集
res = {2, 2}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}, {2}, {2, 2}}
- 结束条件
index >= nums.size()
达成,返回上一层
回溯:
res.pop_back()
->res = {2}
used[2] = false
- 返回上一层
-
回到第五次调用
backtracing(nums, 2, used)
:- 当前子集
res = {2}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}, {2}, {2, 2}}
回溯:
res.pop_back()
->res = {}
used[1] = false
- 返回上一层
- 当前子集
-
回到第一次调用
backtracing(nums, 0, used)
:- 当前子集
res = {}
- 当前结果
result = {``{}, {1}, {1, 2}, {1, 2, 2}, {2}, {2, 2}}
循环3(i = 2):
nums[2] = 2
未使用,且nums[2] == nums[1]
,但used[1] == false
,跳过
- 当前子集
-
结束