40
40
41
41
<!-- 这里可写通用的实现逻辑 -->
42
42
43
- 排序 + 深度优先搜索。
43
+ ** 方法一:排序 + 回溯**
44
+
45
+ 我们可以先对数组进行排序,这样就可以将重复的数字放在一起,方便我们进行去重。
46
+
47
+ 然后,我们设计一个函数 $dfs(i)$,表示当前需要填写第 $i$ 个位置的数。函数的具体实现如下:
48
+
49
+ - 如果 $i = n$,说明我们已经填写完毕,将当前排列加入答案数组中,然后返回。
50
+ - 否则,我们枚举第 $i$ 个位置的数 $nums[ j] $,其中 $j$ 的范围是 $[ 0, n - 1] $。我们需要保证 $nums[ j] $ 没有被使用过,并且与前面枚举的数不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $nums[ j] $,并继续递归地填写下一个位置,即调用 $dfs(i + 1)$。在递归调用结束后,我们需要将 $nums[ j] $ 标记为未使用,以便于进行后面的枚举。
51
+
52
+ 在主函数中,我们首先对数组进行排序,然后调用 $dfs(0)$,即从第 0 个位置开始填写,最终返回答案数组即可。
53
+
54
+ 时间复杂度 $O(n \times n!)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。需要进行 $n!$ 次枚举,每次枚举需要 $O(n)$ 的时间来判断是否重复。另外,我们需要一个标记数组来标记每个位置是否被使用过,因此空间复杂度为 $O(n)$。
55
+
56
+ 相似题目:
57
+
58
+ - [ 46. 全排列] ( /solution/0000-0099/0046.Permutations/README.md )
44
59
45
60
<!-- tabs:start -->
46
61
51
66
``` python
52
67
class Solution :
53
68
def permuteUnique (self , nums : List[int ]) -> List[List[int ]]:
54
- n = len (nums)
55
- res = []
56
- path = [0 ] * n
57
- used = [False ] * n
58
- nums.sort()
59
-
60
- def dfs (u ):
61
- if u == n:
62
- res.append(path.copy())
69
+ def dfs (i : int ):
70
+ if i == n:
71
+ ans.append(t[:])
63
72
return
64
- for i in range (n):
65
- if used[i ] or (i > 0 and nums[i ] == nums[i - 1 ] and not used[i - 1 ]):
73
+ for j in range (n):
74
+ if vis[j ] or (j and nums[j ] == nums[j - 1 ] and not vis[j - 1 ]):
66
75
continue
67
- path[u ] = nums[i ]
68
- used[i ] = True
69
- dfs(u + 1 )
70
- used[i ] = False
76
+ t[i ] = nums[j ]
77
+ vis[j ] = True
78
+ dfs(i + 1 )
79
+ vis[j ] = False
71
80
81
+ n = len (nums)
82
+ nums.sort()
83
+ ans = []
84
+ t = [0 ] * n
85
+ vis = [False ] * n
72
86
dfs(0 )
73
- return res
87
+ return ans
74
88
```
75
89
76
90
### ** Java**
@@ -79,31 +93,33 @@ class Solution:
79
93
80
94
``` java
81
95
class Solution {
96
+ private List<List<Integer > > ans = new ArrayList<> ();
97
+ private List<Integer > t = new ArrayList<> ();
98
+ private int [] nums;
99
+ private boolean [] vis;
100
+
82
101
public List<List<Integer > > permuteUnique (int [] nums ) {
83
- List<List<Integer > > res = new ArrayList<> ();
84
- List<Integer > path = new ArrayList<> ();
85
- int n = nums. length;
86
- boolean [] used = new boolean [n];
87
102
Arrays . sort(nums);
88
- dfs(0 , n, nums, used, path, res);
89
- return res;
103
+ this . nums = nums;
104
+ vis = new boolean [nums. length];
105
+ dfs(0 );
106
+ return ans;
90
107
}
91
108
92
- private void dfs (
93
- int u , int n , int [] nums , boolean [] used , List<Integer > path , List<List<Integer > > res ) {
94
- if (u == n) {
95
- res. add(new ArrayList<> (path));
109
+ private void dfs (int i ) {
110
+ if (i == nums. length) {
111
+ ans. add(new ArrayList<> (t));
96
112
return ;
97
113
}
98
- for (int i = 0 ; i < n ; ++ i ) {
99
- if (used[i ] || (i > 0 && nums[i ] == nums[i - 1 ] && ! used[i - 1 ])) {
114
+ for (int j = 0 ; j < nums . length ; ++ j ) {
115
+ if (vis[j ] || (j > 0 && nums[j ] == nums[j - 1 ] && ! vis[j - 1 ])) {
100
116
continue ;
101
117
}
102
- path . add(nums[i ]);
103
- used[i ] = true ;
104
- dfs(u + 1 , n, nums, used, path, res );
105
- used[i ] = false ;
106
- path . remove(path . size() - 1 );
118
+ t . add(nums[j ]);
119
+ vis[j ] = true ;
120
+ dfs(i + 1 );
121
+ vis[j ] = false ;
122
+ t . remove(t . size() - 1 );
107
123
}
108
124
}
109
125
}
@@ -115,129 +131,126 @@ class Solution {
115
131
class Solution {
116
132
public:
117
133
vector<vector<int >> permuteUnique(vector<int >& nums) {
118
- int n = nums.size();
119
- vector<vector<int >> res;
120
- vector<int > path(n, 0);
121
- vector<bool > used(n, false);
122
134
sort(nums.begin(), nums.end());
123
- dfs(0, n, nums, used, path, res);
124
- return res;
125
- }
126
-
127
- void dfs(int u, int n, vector<int>& nums, vector<bool>& used, vector<int>& path, vector<vector<int>>& res) {
128
- if (u == n) {
129
- res.emplace_back(path);
130
- return;
131
- }
132
- for (int i = 0 ; i < n; ++i) {
133
- if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) continue;
134
- path[u] = nums[i];
135
- used[i] = true;
136
- dfs (u + 1, n, nums, used, path, res);
137
- used[ i] = false;
138
- }
139
- }
140
- };
141
- ```
142
-
143
- ### ** C#**
144
-
145
- ``` cs
146
- using System .Collections .Generic ;
147
- using System .Linq ;
148
-
149
- public class Solution {
150
- public IList <IList <int >> PermuteUnique (int [] nums ) {
151
- var results = new List <IList <int >>();
152
- var temp = new List <int >();
153
- var count = nums .GroupBy (n => n ).ToDictionary (g => g .Key , g => g .Count ());
154
- Search (count , temp , results );
155
- return results ;
156
- }
157
-
158
- private void Search (Dictionary <int , int > count , IList <int > temp , IList <IList <int >> results )
159
- {
160
- if (! count .Any () && temp .Any ())
161
- {
162
- results .Add (new List <int >(temp ));
163
- return ;
164
- }
165
- var keys = count .Keys .ToList ();
166
- foreach (var key in keys )
167
- {
168
- temp .Add (key );
169
- -- count [key ];
170
- if (count [key ] == 0 ) count .Remove (key );
171
- Search (count , temp , results );
172
- temp .RemoveAt (temp .Count - 1 );
173
- if (count .ContainsKey (key ))
174
- {
175
- ++ count [key ];
135
+ int n = nums.size();
136
+ vector<vector<int >> ans;
137
+ vector<int > t(n);
138
+ vector<bool > vis(n);
139
+ function<void(int)> dfs = [ &] (int i) {
140
+ if (i == n) {
141
+ ans.emplace_back(t);
142
+ return;
176
143
}
177
- else
178
- {
179
- count [key ] = 1 ;
144
+ for (int j = 0; j < n; ++j) {
145
+ if (vis[ j] || (j && nums[ j] == nums[ j - 1] && !vis[ j - 1] )) {
146
+ continue;
147
+ }
148
+ t[ i] = nums[ j] ;
149
+ vis[ j] = true;
150
+ dfs(i + 1);
151
+ vis[ j] = false;
180
152
}
181
- }
153
+ };
154
+ dfs(0);
155
+ return ans;
182
156
}
183
- }
157
+ };
184
158
```
185
159
186
160
### **Go**
187
161
188
162
```go
189
- func permuteUnique (nums []int ) [][]int {
190
- n := len (nums)
191
- res := make ([][]int , 0 )
192
- path := make ([]int , n)
193
- used := make ([]bool , n)
163
+ func permuteUnique(nums []int) (ans [][]int) {
194
164
sort.Ints(nums)
195
- dfs (0 , n, nums, used, path, &res)
196
- return res
197
- }
198
-
199
- func dfs (u , n int , nums []int , used []bool , path []int , res *[][]int ) {
200
- if u == n {
201
- t := make ([]int , n)
202
- copy (t, path)
203
- *res = append (*res, t)
204
- return
205
- }
206
- for i := 0 ; i < n; i++ {
207
- if used[i] || (i > 0 && nums[i] == nums[i-1 ] && !used[i-1 ]) {
208
- continue
165
+ n := len(nums)
166
+ t := make([]int, n)
167
+ vis := make([]bool, n)
168
+ var dfs func(int)
169
+ dfs = func(i int) {
170
+ if i == n {
171
+ cp := make([]int, n)
172
+ copy(cp, t)
173
+ ans = append(ans, cp)
174
+ return
175
+ }
176
+ for j := 0; j < n; j++ {
177
+ if vis[j] || (j > 0 && nums[j] == nums[j-1] && !vis[j-1]) {
178
+ continue
179
+ }
180
+ vis[j] = true
181
+ t[i] = nums[j]
182
+ dfs(i + 1)
183
+ vis[j] = false
209
184
}
210
- path[u] = nums[i]
211
- used[i] = true
212
- dfs (u+1 , n, nums, used, path, res)
213
- used[i] = false
214
185
}
186
+ dfs(0)
187
+ return
215
188
}
216
189
```
217
190
218
191
### ** TypeScript**
219
192
220
193
``` ts
221
194
function permuteUnique(nums : number []): number [][] {
195
+ nums .sort ((a , b ) => a - b );
222
196
const n = nums .length ;
223
- const res: number [][] = [];
197
+ const ans: number [][] = [];
198
+ const t: number [] = new Array (n );
199
+ const vis: boolean [] = new Array (n );
224
200
const dfs = (i : number ) => {
225
201
if (i === n ) {
226
- res .push ([... nums ]);
202
+ ans .push (t .slice ());
203
+ return ;
227
204
}
228
- const set = new Set <number >();
229
- for (let j = i ; j < n ; j ++ ) {
230
- if (set .has (nums [j ])) {
205
+ for (let j = 0 ; j < n ; ++ j ) {
206
+ if (vis [j ] || (j > 0 && nums [j ] === nums [j - 1 ] && ! vis [j - 1 ])) {
231
207
continue ;
232
208
}
233
- set . add ( nums [j ]) ;
234
- [ nums [ i ], nums [ j ]] = [ nums [ j ], nums [ i ]] ;
209
+ t [ i ] = nums [j ];
210
+ vis [ j ] = true ;
235
211
dfs (i + 1 );
236
- [ nums [ i ], nums [ j ]] = [ nums [ j ], nums [ i ]] ;
212
+ vis [ j ] = false ;
237
213
}
238
214
};
239
215
dfs (0 );
240
- return res ;
216
+ return ans ;
217
+ }
218
+ ```
219
+
220
+ ### ** C#**
221
+
222
+ ``` cs
223
+ public class Solution {
224
+ private List <IList <int >> ans = new List <IList <int >>();
225
+ private List <int > t = new List <int >();
226
+ private int [] nums ;
227
+ private bool [] vis ;
228
+
229
+ public IList <IList <int >> PermuteUnique (int [] nums ) {
230
+ Array .Sort (nums );
231
+ int n = nums .Length ;
232
+ vis = new bool [n ];
233
+ this .nums = nums ;
234
+ dfs (0 );
235
+ return ans ;
236
+ }
237
+
238
+ private void dfs (int i ) {
239
+ if (i == nums .Length ) {
240
+ ans .Add (new List <int >(t ));
241
+ return ;
242
+ }
243
+ for (int j = 0 ; j < nums .Length ; ++ j ) {
244
+ if (vis [j ] || (j > 0 && nums [j ] == nums [j - 1 ] && ! vis [j - 1 ])) {
245
+ continue ;
246
+ }
247
+ vis [j ] = true ;
248
+ t .Add (nums [j ]);
249
+ dfs (i + 1 );
250
+ t .RemoveAt (t .Count - 1 );
251
+ vis [j ] = false ;
252
+ }
253
+ }
241
254
}
242
255
```
243
256
0 commit comments