functionbacktrack(list, tempList, nums, start) {list.push([...tempList]);for (let i = start; i <nums.length; i++) {// 和78.subsets的区别在于这道题nums可以有重复// 因此需要过滤这种情况if (i > start && nums[i] === nums[i -1]) continue;tempList.push(nums[i]);backtrack(list, tempList, nums, i +1);tempList.pop(); }}/** * @param{number[]} nums * @return{number[][]} */varsubsetsWithDup=function (nums) {constlist= [];backtrack( list, [],nums.sort((a, b) => a - b),0, [] );return list;};
C++ Code:
classSolution {private:voidsubsetsWithDup(vector<int>& nums,size_t start,vector<int>& tmp,vector<vector<int>>& res) {res.push_back(tmp);for (auto i = start; i <nums.size(); ++i) {if (i > start &&nums[i] ==nums[i -1]) continue;tmp.push_back(nums[i]);subsetsWithDup(nums, i +1, tmp, res);tmp.pop_back(); } }public:vector<vector<int>> subsetsWithDup(vector<int>& nums) {auto tmp =vector<int>();auto res =vector<vector<int>>();sort(nums.begin(),nums.end());subsetsWithDup(nums,0, tmp, res);return res; }};
Python Code:
classSolution:defsubsetsWithDup(self,nums: List[int],sorted:bool=False) -> List[List[int]]:"""回溯法,通过排序参数避免重复排序"""ifnot nums:return [[]]eliflen(nums)==1:return [[], nums]else:# 先排序,以便去重# 注意,这道题排序花的时间比较多# 因此,增加一个参数,使后续过程不用重复排序,可以大幅提高时间效率ifnotsorted: nums.sort()# 回溯法 pre_lists = self.subsetsWithDup(nums[:-1], sorted=True) all_lists = [i+[nums[-1]] for i in pre_lists] + pre_lists# 去重 result = []for i in all_lists:if i notin result: result.append(i)return result