Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3f772f3

Browse files
feat: add solutions to lcci problem: No.08.08 (doocs#1659)
No.08.08.Permutation II
1 parent dc5512a commit 3f772f3

File tree

8 files changed

+514
-84
lines changed

8 files changed

+514
-84
lines changed

‎lcci/08.08.Permutation II/README.md‎

Lines changed: 184 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。</p>
910
<p><strong>示例1:</strong></p>
1011
<pre><strong> 输入</strong>:S = &quot;qqe&quot;
@@ -24,22 +25,182 @@
2425

2526
<!-- 这里可写通用的实现逻辑 -->
2627

28+
**方法一:排序 + 回溯**
29+
30+
我们可以先对字符串按照字符进行排序,这样就可以将重复的字符放在一起,方便我们进行去重。
31+
32+
然后,我们设计一个函数 $dfs(i),ドル表示当前需要填写第 $i$ 个位置的字符。函数的具体实现如下:
33+
34+
- 如果 $i = n,ドル说明我们已经填写完毕,将当前排列加入答案数组中,然后返回。
35+
- 否则,我们枚举第 $i$ 个位置的字符 $s[j],ドル其中 $j$ 的范围是 $[0, n - 1]$。我们需要保证 $s[j]$ 没有被使用过,并且与前面枚举的字符不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 $s[j],ドル并继续递归地填写下一个位置,即调用 $dfs(i + 1)$。在递归调用结束后,我们需要将 $s[j]$ 标记为未使用,以便于进行后面的枚举。
36+
37+
在主函数中,我们首先对字符串进行排序,然后调用 $dfs(0),ドル即从第 0ドル$ 个位置开始填写,最终返回答案数组即可。
38+
39+
时间复杂度 $O(n \times n!),ドル空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。需要进行 $n!$ 次枚举,每次枚举需要 $O(n)$ 的时间来判断是否重复。另外,我们需要一个标记数组来标记每个位置是否被使用过,因此空间复杂度为 $O(n)$。
40+
2741
<!-- tabs:start -->
2842

2943
### **Python3**
3044

3145
<!-- 这里可写当前语言的特殊实现逻辑 -->
3246

3347
```python
34-
48+
class Solution:
49+
def permutation(self, S: str) -> List[str]:
50+
def dfs(i: int):
51+
if i == n:
52+
ans.append("".join(t))
53+
return
54+
for j in range(n):
55+
if vis[j] or (j and cs[j] == cs[j - 1] and not vis[j - 1]):
56+
continue
57+
t[i] = cs[j]
58+
vis[j] = True
59+
dfs(i + 1)
60+
vis[j] = False
61+
62+
cs = sorted(S)
63+
n = len(cs)
64+
ans = []
65+
t = [None] * n
66+
vis = [False] * n
67+
dfs(0)
68+
return ans
3569
```
3670

3771
### **Java**
3872

3973
<!-- 这里可写当前语言的特殊实现逻辑 -->
4074

4175
```java
76+
class Solution {
77+
private int n;
78+
private char[] cs;
79+
private List<String> ans = new ArrayList<>();
80+
private boolean[] vis;
81+
private StringBuilder t = new StringBuilder();
82+
83+
public String[] permutation(String S) {
84+
cs = S.toCharArray();
85+
n = cs.length;
86+
Arrays.sort(cs);
87+
vis = new boolean[n];
88+
dfs(0);
89+
return ans.toArray(new String[0]);
90+
}
91+
92+
private void dfs(int i) {
93+
if (i == n) {
94+
ans.add(t.toString());
95+
return;
96+
}
97+
for (int j = 0; j < n; ++j) {
98+
if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] == cs[j - 1])) {
99+
continue;
100+
}
101+
vis[j] = true;
102+
t.append(cs[j]);
103+
dfs(i + 1);
104+
t.deleteCharAt(t.length() - 1);
105+
vis[j] = false;
106+
}
107+
}
108+
}
109+
```
42110

111+
### **C++**
112+
113+
```cpp
114+
class Solution {
115+
public:
116+
vector<string> permutation(string S) {
117+
vector<char> cs(S.begin(), S.end());
118+
sort(cs.begin(), cs.end());
119+
int n = cs.size();
120+
vector<string> ans;
121+
vector<bool> vis(n);
122+
string t;
123+
function<void(int)> dfs = [&](int i) {
124+
if (i == n) {
125+
ans.push_back(t);
126+
return;
127+
}
128+
for (int j = 0; j < n; ++j) {
129+
if (vis[j] || (j && !vis[j - 1] && cs[j] == cs[j - 1])) {
130+
continue;
131+
}
132+
vis[j] = true;
133+
t.push_back(cs[j]);
134+
dfs(i + 1);
135+
t.pop_back();
136+
vis[j] = false;
137+
}
138+
};
139+
dfs(0);
140+
return ans;
141+
}
142+
};
143+
```
144+
145+
### **Go**
146+
147+
```go
148+
func permutation(S string) (ans []string) {
149+
cs := []byte(S)
150+
sort.Slice(cs, func(i, j int) bool { return cs[i] < cs[j] })
151+
t := []byte{}
152+
n := len(cs)
153+
vis := make([]bool, n)
154+
var dfs func(int)
155+
dfs = func(i int) {
156+
if i == n {
157+
ans = append(ans, string(t))
158+
return
159+
}
160+
for j := 0; j < n; j++ {
161+
if vis[j] || (j > 0 && !vis[j-1] && cs[j] == cs[j-1]) {
162+
continue
163+
}
164+
vis[j] = true
165+
t = append(t, cs[j])
166+
dfs(i + 1)
167+
t = t[:len(t)-1]
168+
vis[j] = false
169+
}
170+
}
171+
dfs(0)
172+
return
173+
}
174+
```
175+
176+
### **TypeScript**
177+
178+
```ts
179+
function permutation(S: string): string[] {
180+
const cs: string[] = S.split('').sort();
181+
const ans: string[] = [];
182+
const n = cs.length;
183+
const vis: boolean[] = Array(n).fill(false);
184+
const t: string[] = [];
185+
const dfs = (i: number) => {
186+
if (i === n) {
187+
ans.push(t.join(''));
188+
return;
189+
}
190+
for (let j = 0; j < n; ++j) {
191+
if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
192+
continue;
193+
}
194+
vis[j] = true;
195+
t.push(cs[j]);
196+
dfs(i + 1);
197+
t.pop();
198+
vis[j] = false;
199+
}
200+
};
201+
dfs(0);
202+
return ans;
203+
}
43204
```
44205

45206
### **JavaScript**
@@ -50,35 +211,30 @@
50211
* @return {string[]}
51212
*/
52213
var permutation = function (S) {
53-
let res = [];
54-
let arr = [...S];
55-
arr.sort();
56-
let prev = [];
57-
let record = new Array(S.length).fill(false);
58-
dfs(arr, 0, prev, record, res);
59-
return res;
60-
};
61-
function dfs(arr, depth, prev, record, res) {
62-
if (depth == arr.length) {
63-
res.push(prev.join(''));
64-
return;
65-
}
66-
for (let i = 0; i < arr.length; i++) {
67-
if (record[i]) {
68-
continue;
214+
const cs = S.split('').sort();
215+
const ans = [];
216+
const n = cs.length;
217+
const vis = Array(n).fill(false);
218+
const t = [];
219+
const dfs = i => {
220+
if (i === n) {
221+
ans.push(t.join(''));
222+
return;
69223
}
70-
// 剪枝
71-
if (i > 0 && arr[i] == arr[i - 1] && record[i - 1]) {
72-
continue;
224+
for (let j = 0; j < n; ++j) {
225+
if (vis[j] || (j > 0 && !vis[j - 1] && cs[j] === cs[j - 1])) {
226+
continue;
227+
}
228+
vis[j] = true;
229+
t.push(cs[j]);
230+
dfs(i + 1);
231+
t.pop();
232+
vis[j] = false;
73233
}
74-
prev.push(arr[i]);
75-
record[i] = true;
76-
dfs(arr, depth + 1, prev, record, res);
77-
// 回溯
78-
prev.pop();
79-
record[i] = false;
80-
}
81-
}
234+
};
235+
dfs(0);
236+
return ans;
237+
};
82238
```
83239

84240
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /