-
Notifications
You must be signed in to change notification settings - Fork 0
/
0090.SubsetsII.js
153 lines (111 loc) · 3.24 KB
/
0090.SubsetsII.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Given an integer array nums that may contain duplicates, return all possible subsets (the power set).
// The solution set must not contain duplicate subsets. Return the solution in any order.
//
// Example 1:
// Input: nums = [1,2,2]
// Output: [[],[1],[1,2],[1,2,2],[2],[2,2]]
// Example 2:
// Input: nums = [0]
// Output: [[],[0]]
//
// Constraints:
// 1 <= nums.length <= 10
// -10 <= nums[i] <= 10
// 来源:力扣(LeetCode)
// 链接:https://leetcode-cn.com/problems/subsets-ii
// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
// 🎨 方法一:回溯
// 📝 思路:先排序,利用set去重,同 0078.Subsets
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsetsWithDup = function (nums) {
nums.sort((a, b) => a - b);
const set = new Set();
const target = [];
/**
* 深度优先遍历数组nums
* @param {*} nums
* @param {*} deep 深度/宽度
* @returns
*/
const dfs = (nums, deep) => {
if (deep >= nums.length) {
set.add(JSON.stringify([...target]));
return
}
target.push(nums[deep]);
dfs(nums, deep + 1);
target.pop();
dfs(nums, deep + 1);
}
dfs(nums, 0);
const ans = [];
for (let [_, val] of set.entries()) {
ans.push(JSON.parse(val));
}
return ans
};
// 🎨 方法一:回溯 - 优化
// 📝 思路:https://leetcode-cn.com/problems/subsets-ii/solution/90-zi-ji-iiche-di-li-jie-zi-ji-wen-ti-ru-djmf/
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsetsWithDup = function (nums) {
// 去重需要排序
nums.sort((a, b) => a - b);
const ans = [];
const target = [];
/**
* 深度优先遍历数组nums
* @param {*} nums
* @param {*} deep 深度/宽度
* @param {*} choosePre 是否选择上一个元素
* @returns
*/
const dfs = (nums, deep, choosePre) => {
if (deep >= nums.length) {
ans.push(target.slice());
return
}
dfs(nums, deep + 1, false);
// 🔥树层去重区别与树枝去重:递归时,若发现没有选择上一个数,且当前数字与上一个数相同,则可以跳过当前生成的子集
if (!choosePre && nums[deep - 1] === nums[deep]) {
return
}
target.push(nums[deep]);
dfs(nums, deep + 1, true);
target.pop();
}
dfs(nums, 0, false);
return ans
};
// 🎨 方法一:回溯 - 优化 - 宁一种实现
// 📝 思路:https://leetcode-cn.com/problems/subsets-ii/solution/90-zi-ji-iiche-di-li-jie-zi-ji-wen-ti-ru-djmf/
/**
* @param {number[]} nums
* @return {number[][]}
*/
var subsetsWithDup = function (nums) {
let ans = []
let path = []
nums.sort((a, b) => a - b);
function dfs(nums, deep) {
ans.push(path.slice(0))
if (deep >= nums.length) {
return
}
for (let i = deep; i < nums.length; i++) {
if (i > deep && nums[i] === nums[i - 1]) {
continue
}
path.push(nums[i])
dfs(nums, i + 1)
path.pop()
}
}
dfs(0, nums)
return ans
};