28
28
29
29
<!-- 这里可写通用的实现逻辑 -->
30
30
31
+ ** 方法一:回溯 + 哈希表**
32
+
33
+ 我们设计一个函数 $dfs(i)$,表示当前排列到了第 $i$ 个位置,我们需要在第 $i$ 个位置上填入一个字符,这个字符可以从 $s[ i..n-1] $ 中任意选择。
34
+
35
+ 函数 $dfs(i)$ 的执行过程如下:
36
+
37
+ - 如果 $i = n-1$,说明当前排列已经填满,将当前排列加入答案,返回。
38
+ - 否则,我们需要在 $s[ i..n-1] $ 中选择一个字符填入第 $i$ 个位置,我们可以使用哈希表记录哪些字符已经被填过,从而避免重复填入相同的字符。
39
+ - 在 $s[ i..n-1] $ 中选择一个字符填入第 $i$ 个位置,然后递归执行函数 $dfs(i+1)$,即填入第 $i+1$ 个位置。
40
+ - 回溯,撤销选择,即将第 $i$ 个位置的字符填回原位。
41
+
42
+ 我们在主函数中调用函数 $dfs(0)$,即从第 0 个位置开始填入字符。最后返回答案数组即可。
43
+
44
+ 时间复杂度 $O(n! \times n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。需要进行 $n!$ 次排列,每次排列需要 $O(n)$ 的时间复制字符串。
45
+
31
46
<!-- tabs:start -->
32
47
33
48
### ** Python3**
37
52
``` python
38
53
class Solution :
39
54
def permutation (self , s : str ) -> List[str ]:
40
- def dfs (x ):
41
- if x == len (s) - 1 :
42
- res .append(" " .join(chars ))
55
+ def dfs (i ):
56
+ if i == len (s) - 1 :
57
+ ans .append(' ' .join(cs ))
43
58
return
44
- t = set ()
45
- for i in range (x , len (s)):
46
- if chars[i] in t :
47
- continue
48
- t.add(chars [i])
49
- chars[i], chars[x] = chars[x], chars[i]
50
- dfs(x + 1 )
51
- chars[i], chars[x] = chars[x], chars[i]
52
-
53
- chars, res = list (s), []
59
+ vis = set ()
60
+ for j in range (i , len (s)):
61
+ if cs[j] not in vis :
62
+ vis.add(cs[j])
63
+ cs [i], cs[j] = cs[j], cs[i]
64
+ dfs(i + 1 )
65
+ cs[i], cs[j] = cs[j], cs[i]
66
+
67
+ ans = []
68
+ cs = list (s)
54
69
dfs(0 )
55
- return res
70
+ return ans
56
71
```
57
72
58
73
### ** Java**
@@ -61,38 +76,89 @@ class Solution:
61
76
62
77
``` java
63
78
class Solution {
64
- private char [] chars ;
65
- private List< String > res ;
79
+ private List< String > ans = new ArrayList<> () ;
80
+ private char [] cs ;
66
81
67
82
public String [] permutation (String s ) {
68
- chars = s. toCharArray();
69
- res = new ArrayList<> ();
83
+ cs = s. toCharArray();
70
84
dfs(0 );
71
- return res . toArray(new String [res . size()]);
85
+ return ans . toArray(new String [ans . size()]);
72
86
}
73
87
74
- private void dfs (int x ) {
75
- if (x == chars . length - 1 ) {
76
- res . add(String . valueOf(chars ));
88
+ private void dfs (int i ) {
89
+ if (i == cs . length - 1 ) {
90
+ ans . add(String . valueOf(cs ));
77
91
return ;
78
92
}
79
- Set<Character > set = new HashSet<> ();
80
- for (int i = x; i < chars. length; ++ i) {
81
- if (set. contains(chars[i])) {
82
- continue ;
93
+ Set<Character > vis = new HashSet<> ();
94
+ for (int j = i; j < cs. length; ++ j) {
95
+ if (vis. add(cs[j])) {
96
+ swap(i, j);
97
+ dfs(i + 1 );
98
+ swap(i, j);
83
99
}
84
- set. add(chars[i]);
85
- swap(i, x);
86
- dfs(x + 1 );
87
- swap(i, x);
88
100
}
89
101
}
90
102
91
103
private void swap (int i , int j ) {
92
- char t = chars[i];
93
- chars[i] = chars[j];
94
- chars[j] = t;
104
+ char t = cs[i];
105
+ cs[i] = cs[j];
106
+ cs[j] = t;
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### ** C++**
112
+
113
+ ``` cpp
114
+ class Solution {
115
+ public:
116
+ vector<string > permutation(string s) {
117
+ vector<string > ans;
118
+ function<void(int)> dfs = [ &] (int i) {
119
+ if (i == s.size() - 1) {
120
+ ans.push_back(s);
121
+ return;
122
+ }
123
+ unordered_set<char > vis;
124
+ for (int j = i; j < s.size(); ++j) {
125
+ if (!vis.count(s[ j] )) {
126
+ vis.insert(s[ j] );
127
+ swap(s[ i] , s[ j] );
128
+ dfs(i + 1);
129
+ swap(s[ i] , s[ j] );
130
+ }
131
+ }
132
+ };
133
+ dfs(0);
134
+ return ans;
95
135
}
136
+ };
137
+ ```
138
+
139
+ ### **Go**
140
+
141
+ ```go
142
+ func permutation(s string) (ans []string) {
143
+ cs := []byte(s)
144
+ var dfs func(int)
145
+ dfs = func(i int) {
146
+ if i == len(s)-1 {
147
+ ans = append(ans, string(cs))
148
+ return
149
+ }
150
+ vis := map[byte]bool{}
151
+ for j := i; j < len(s); j++ {
152
+ if !vis[cs[j]] {
153
+ vis[cs[j]] = true
154
+ cs[i], cs[j] = cs[j], cs[i]
155
+ dfs(i + 1)
156
+ cs[i], cs[j] = cs[j], cs[i]
157
+ }
158
+ }
159
+ }
160
+ dfs(0)
161
+ return
96
162
}
97
163
```
98
164
@@ -104,52 +170,26 @@ class Solution {
104
170
* @return {string[]}
105
171
*/
106
172
var permutation = function (s ) {
107
- let len = s .length ;
108
- let res = new Set ();
109
- function dfs (str , isRead ) {
110
- if (str .length === len) {
111
- res .add (str);
173
+ const cs = s .split (' ' );
174
+ const ans = [];
175
+ const n = s .length ;
176
+ const dfs = i => {
177
+ if (i == n - 1 ) {
178
+ ans .push (cs .join (' ' ));
112
179
return ;
113
180
}
114
- for (let i = 0 ; i < len; i++ ) {
115
- if (isRead[i]) continue ;
116
- isRead[i] = 1 ;
117
- dfs (str .concat (s[i]), isRead);
118
- isRead[i] = 0 ;
119
- }
120
- }
121
- dfs (' ' , {});
122
- return [... res];
123
- };
124
- ```
125
-
126
- ### ** C++**
127
-
128
- ``` cpp
129
- class Solution {
130
- public:
131
- void func(string str, int index, set<string >& mySet) {
132
- if (index == str.size()) {
133
- mySet.insert(str);
134
- } else {
135
- for (int i = index; i < str.size(); i++) {
136
- swap(str[ i] , str[ index] );
137
- int temp = index + 1;
138
- func(str, temp, mySet);
139
- swap(str[ i] , str[ index] );
181
+ const vis = new Set ();
182
+ for (let j = i; j < n; ++ j) {
183
+ if (! vis .has (cs[j])) {
184
+ vis .add (cs[j]);
185
+ [cs[i], cs[j]] = [cs[j], cs[i]];
186
+ dfs (i + 1 );
187
+ [cs[i], cs[j]] = [cs[j], cs[i]];
140
188
}
141
189
}
142
- }
143
-
144
- vector<string> permutation(string s) {
145
- set<string> mySet;
146
- func(s, 0, mySet);
147
- vector<string> ret;
148
- for (string x : mySet) {
149
- ret.push_back(x);
150
- }
151
- return ret;
152
- }
190
+ };
191
+ dfs (0 );
192
+ return ans;
153
193
};
154
194
```
155
195
@@ -211,25 +251,26 @@ impl Solution {
211
251
212
252
``` cs
213
253
public class Solution {
254
+ private char [] cs ;
255
+ private List <string > ans = new List <string >();
256
+
214
257
public string [] Permutation (string s ) {
215
- int n = s .Length ;
216
- var data = s .ToCharArray ();
217
- var ans = new List <string >();
218
- DFS (data , 0 , ans );
258
+ cs = s .ToCharArray ();
259
+ dfs (0 );
219
260
return ans .ToArray ();
220
261
}
221
262
222
- void DFS ( char [] s , int idx , List < string > ans ) {
223
- if (idx == s .Length ) {
224
- ans .Add (new string (s ));
263
+ private void dfs ( int i ) {
264
+ if (i == cs .Length - 1 ) {
265
+ ans .Add (new string (cs ));
225
266
return ;
226
267
}
227
- var set = new HashSet <char >();
228
- for (int i = idx ; i < s .Length ; i ++ ) {
229
- if (set .Add (s [ i ])) {
230
- (s [i], s[idx ]) = (s [ idx ], s [i ]);
231
- DFS ( s , idx + 1 , ans );
232
- (s [i], s[idx ]) = (s [ idx ], s [i ]);
268
+ var vis = new HashSet <char >();
269
+ for (int j = i ; j < cs .Length ; ++ j ) {
270
+ if (vis .Add (cs [ j ])) {
271
+ (cs [i], cs[j ]) = (cs [ j ], cs [i ]);
272
+ dfs ( i + 1 );
273
+ (cs [i], cs[j ]) = (cs [ j ], cs [i ]);
233
274
}
234
275
}
235
276
}
0 commit comments