Skip to content

Commit dc5f255

Browse files
committed
feat: add solutions to lcof problem: No.38
1 parent c35e35b commit dc5f255

File tree

9 files changed

+230
-167
lines changed

9 files changed

+230
-167
lines changed

lcof/面试题14- I. 剪绳子/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ $$
4040

4141
**方法二:数学**
4242

43-
当 $n \lt 4$ 时,$n$ 不能拆分成至少两个正整数的和,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
43+
当 $n \lt 4$,此时 $n$ 不能拆分成至少两个正整数的和,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
4444

4545
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
4646

lcof/面试题14- II. 剪绳子 II/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
**方法一:数学(快速幂)**
3636

37-
当 $n \lt 4$ 时,$n$ 不能拆分成至少两个正整数的和,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
37+
当 $n \lt 4$,此时 $n$ 不能拆分成至少两个正整数的和,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
3838

3939
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
4040

lcof/面试题38. 字符串的排列/README.md

+129-88
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@
2828

2929
<!-- 这里可写通用的实现逻辑 -->
3030

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+
3146
<!-- tabs:start -->
3247

3348
### **Python3**
@@ -37,22 +52,22 @@
3752
```python
3853
class Solution:
3954
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))
4358
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)
5469
dfs(0)
55-
return res
70+
return ans
5671
```
5772

5873
### **Java**
@@ -61,38 +76,89 @@ class Solution:
6176

6277
```java
6378
class Solution {
64-
private char[] chars;
65-
private List<String> res;
79+
private List<String> ans = new ArrayList<>();
80+
private char[] cs;
6681

6782
public String[] permutation(String s) {
68-
chars = s.toCharArray();
69-
res = new ArrayList<>();
83+
cs = s.toCharArray();
7084
dfs(0);
71-
return res.toArray(new String[res.size()]);
85+
return ans.toArray(new String[ans.size()]);
7286
}
7387

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));
7791
return;
7892
}
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);
8399
}
84-
set.add(chars[i]);
85-
swap(i, x);
86-
dfs(x + 1);
87-
swap(i, x);
88100
}
89101
}
90102

91103
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;
95135
}
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
96162
}
97163
```
98164

@@ -104,52 +170,26 @@ class Solution {
104170
* @return {string[]}
105171
*/
106172
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(''));
112179
return;
113180
}
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]];
140188
}
141189
}
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;
153193
};
154194
```
155195

@@ -211,25 +251,26 @@ impl Solution {
211251

212252
```cs
213253
public class Solution {
254+
private char[] cs;
255+
private List<string> ans = new List<string>();
256+
214257
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);
219260
return ans.ToArray();
220261
}
221262

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));
225266
return;
226267
}
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]);
233274
}
234275
}
235276
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
class Solution {
22
public:
3-
void func(string str, int index, set<string>& mySet) {
4-
if (index == str.size()) {
5-
mySet.insert(str);
6-
} else {
7-
for (int i = index; i < str.size(); i++) {
8-
swap(str[i], str[index]);
9-
int temp = index + 1;
10-
func(str, temp, mySet);
11-
swap(str[i], str[index]);
12-
}
13-
}
14-
}
15-
163
vector<string> permutation(string s) {
17-
set<string> mySet;
18-
func(s, 0, mySet);
19-
vector<string> ret;
20-
for (string x : mySet) {
21-
ret.push_back(x);
22-
}
23-
return ret;
4+
vector<string> ans;
5+
function<void(int)> dfs = [&](int i) {
6+
if (i == s.size() - 1) {
7+
ans.push_back(s);
8+
return;
9+
}
10+
unordered_set<char> vis;
11+
for (int j = i; j < s.size(); ++j) {
12+
if (!vis.count(s[j])) {
13+
vis.insert(s[j]);
14+
swap(s[i], s[j]);
15+
dfs(i + 1);
16+
swap(s[i], s[j]);
17+
}
18+
}
19+
};
20+
dfs(0);
21+
return ans;
2422
}
2523
};

lcof/面试题38. 字符串的排列/Solution.cs

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
public class Solution {
2+
private char[] cs;
3+
private List<string> ans = new List<string>();
4+
25
public string[] Permutation(string s) {
3-
var data = s.ToCharArray();
4-
var ans = new List<string>();
5-
DFS(data, 0, ans);
6+
cs = s.ToCharArray();
7+
dfs(0);
68
return ans.ToArray();
79
}
810

9-
void DFS(char[] s, int idx, List<string> ans) {
10-
if (idx == s.Length) {
11-
ans.Add(new string(s));
11+
private void dfs(int i) {
12+
if (i == cs.Length - 1) {
13+
ans.Add(new string(cs));
1214
return;
1315
}
14-
var set = new HashSet<char>();
15-
for (int i = idx; i < s.Length; i++) {
16-
if (set.Add(s[i])) {
17-
(s[i], s[idx]) = (s[idx], s[i]);
18-
DFS(s, idx+1, ans);
19-
(s[i], s[idx]) = (s[idx], s[i]);
16+
var vis = new HashSet<char>();
17+
for (int j = i; j < cs.Length; ++j) {
18+
if (vis.Add(cs[j])) {
19+
(cs[i], cs[j]) = (cs[j], cs[i]);
20+
dfs(i + 1);
21+
(cs[i], cs[j]) = (cs[j], cs[i]);
2022
}
2123
}
2224
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
func permutation(s string) (ans []string) {
2+
cs := []byte(s)
3+
var dfs func(int)
4+
dfs = func(i int) {
5+
if i == len(s)-1 {
6+
ans = append(ans, string(cs))
7+
return
8+
}
9+
vis := map[byte]bool{}
10+
for j := i; j < len(s); j++ {
11+
if !vis[cs[j]] {
12+
vis[cs[j]] = true
13+
cs[i], cs[j] = cs[j], cs[i]
14+
dfs(i + 1)
15+
cs[i], cs[j] = cs[j], cs[i]
16+
}
17+
}
18+
}
19+
dfs(0)
20+
return
21+
}

0 commit comments

Comments
 (0)