
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,跳过
- 当前子集
-
结束