题目描述
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例1:
输入: nums = [1,2,2]
输出: [[],[1],[1,2],[1,2,2],[2],[2,2]]
思路
- 本题与子集 思路一本一致,唯一不同点是多了去重的操作
- 本题的去重应该怎么来去呢?
- 首先画出抽象树结构
- 由上图我们可以知道去重逻辑为:
nums[i]==nums[i-1]&&used[i-1]=false前一个元素与本元素相等并且前一个元素在本轮选择中未被使用。 - 很重要的点:数组必须是一个递增数组,也就是要
排序
代码
function subsetsWithDup(nums: number[]): number[][] {
let result=[],path=[],used=new Array(nums.length).fill(false);//结果数组,路径数组
result.push([]);
// 排序
nums.sort((a,b)=>a-b);
function backTracking(nums: number[],startIndex:number): void{
//终止条件
if(startIndex==nums.length){
return;
}
for(let i=startIndex;i<nums.length;i++){
// 去重逻辑
if(i>0&&nums[i]==nums[i-1]&&!used[i-1]){
continue;
}
path.push(nums[i]);
used[i]=true
result.push([...path]); //收割每层递归结果
backTracking(nums,i+1);
path.pop(); // 回溯操作
used[i]=false;
}
}
backTracking(nums,0)
return result;
};
总结
本题是子集与组合总和思路的结合体,既有单层收割也有树层去重。