90 子集2-中等
题目:
给你一个整数数组 nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2] 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0] 输出:[[],[0]]
分析:
这道题跟 78 题类似,两者的区别是:
78 题,给定的数组中元素不重复,返回所有的子集
这道题,给定的数组中元素有重复,返回所有子集,要求子集去重。
核心思路还是回溯,增加两个辅助条件:
回溯前,对数组进行排序,方便回溯的时候跳过重复元素
回溯过程中,剪枝优化。剪枝的关键是初次遍历不剪枝,下一次的时候,如果元素跟前一个元素相同,直接跳过回溯。
// date 2023/12/26
func subsetsWithDup(nums []int) [][]int {
res := make([][]int, 0, 16)
var backtrack func(start int, temp []int)
backtrack = func(start int, temp []int) {
one := make([]int, len(temp))
copy(one, temp)
res = append(res, one)
for i := start; i < len(nums); i++ {
// 去重的关键,本次不去重,下一次去重
for i < len(nums) && i > start && nums[i] == nums[i-1] {
i++
continue
}
// 注意判断,去重后是否越界
if i >= len(nums) {
break
}
temp = append(temp, nums[i])
backtrack(i+1, temp)
temp = temp[:len(temp)-1]
}
}
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
backtrack(0, []int{})
return res
}
最后更新于