Skip to content

Commit c701e89

Browse files
committed
feat: add solutions to lc problem: No.0514
No.0514.Freedom Trail
1 parent 6cdee56 commit c701e89

File tree

7 files changed

+384
-6
lines changed

7 files changed

+384
-6
lines changed

Diff for: solution/0500-0599/0514.Freedom Trail/README.md

+139-1
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,160 @@
5858

5959
<!-- 这里可写通用的实现逻辑 -->
6060

61+
**方法一:动态规划**
62+
63+
我们首先预处理出字符串 $ring$ 中每个字符 $c$ 出现的位置列表,记录在数组 $pos[c]$ 中。不妨假设字符串 $key$ 和 $ring$ 的长度分别为 $m$ 和 $n$。
64+
65+
然后我们定义 $f[i][j]$ 表示拼写完字符串 $key$ 的前 $i+1$ 个字符,且 $ring$ 的第 $j$ 个字符与 $12:00$ 方向对齐的最少步数。初始时 $f[i][j]=+\infty$。答案为 $\min_{0 \leq j < n} f[m - 1][j]$。
66+
67+
我们可以先初始化 $f[0][j]$,其中 $j$ 是字符 $key[0]$ 在 $ring$ 中出现的位置。由于 $ring$ 的第 $j$ 个字符与 $12:00$ 方向对齐,因此我们只需要 $1$ 步即可拼写出 $key[0]$。此外,我们还需要 $min(j, n - j)$ 步将 $ring$ 旋转到 $12:00$ 方向。因此 $f[0][j]=min(j, n - j) + 1$。
68+
69+
接下来,我们考虑当 $i \geq 1$ 时,状态如何转移。我们可以枚举 $key[i]$ 在 $ring$ 中的位置列表 $pos[key[i]]$,并枚举 $key[i-1]$ 在 $ring$ 中的位置列表 $pos[key[i-1]]$,然后更新 $f[i][j]$,即 $f[i][j]=\min_{k \in pos[key[i-1]]} f[i-1][k] + \min(\text{abs}(j - k), n - \text{abs}(j - k)) + 1$。
70+
71+
最后,我们返回 $\min_{0 \leq j \lt n} f[m - 1][j]$ 即可。
72+
73+
时间复杂度 $O(m \times n^2)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是字符串 $key$ 和 $ring$ 的长度。
74+
6175
<!-- tabs:start -->
6276

6377
### **Python3**
6478

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

6781
```python
68-
82+
class Solution:
83+
def findRotateSteps(self, ring: str, key: str) -> int:
84+
m, n = len(key), len(ring)
85+
pos = defaultdict(list)
86+
for i, c in enumerate(ring):
87+
pos[c].append(i)
88+
f = [[inf] * n for _ in range(m)]
89+
for j in pos[key[0]]:
90+
f[0][j] = min(j, n - j) + 1
91+
for i in range(1, m):
92+
for j in pos[key[i]]:
93+
for k in pos[key[i - 1]]:
94+
f[i][j] = min(
95+
f[i][j], f[i - 1][k] + min(abs(j - k), n - abs(j - k)) + 1
96+
)
97+
return min(f[-1][j] for j in pos[key[-1]])
6998
```
7099

71100
### **Java**
72101

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

75104
```java
105+
class Solution {
106+
public int findRotateSteps(String ring, String key) {
107+
int m = key.length(), n = ring.length();
108+
List<Integer>[] pos = new List[26];
109+
Arrays.setAll(pos, k -> new ArrayList<>());
110+
for (int i = 0; i < n; ++i) {
111+
int j = ring.charAt(i) - 'a';
112+
pos[j].add(i);
113+
}
114+
int[][] f = new int[m][n];
115+
for (var g : f) {
116+
Arrays.fill(g, 1 << 30);
117+
}
118+
for (int j : pos[key.charAt(0) - 'a']) {
119+
f[0][j] = Math.min(j, n - j) + 1;
120+
}
121+
for (int i = 1; i < m; ++i) {
122+
for (int j : pos[key.charAt(i) - 'a']) {
123+
for (int k : pos[key.charAt(i - 1) - 'a']) {
124+
f[i][j] = Math.min(f[i][j], f[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1);
125+
}
126+
}
127+
}
128+
int ans = 1 << 30;
129+
for (int j : pos[key.charAt(m - 1) - 'a']) {
130+
ans = Math.min(ans, f[m - 1][j]);
131+
}
132+
return ans;
133+
}
134+
}
135+
```
136+
137+
### **C++**
138+
139+
```cpp
140+
class Solution {
141+
public:
142+
int findRotateSteps(string ring, string key) {
143+
int m = key.size(), n = ring.size();
144+
vector<int> pos[26];
145+
for (int j = 0; j < n; ++j) {
146+
pos[ring[j] - 'a'].push_back(j);
147+
}
148+
int f[m][n];
149+
memset(f, 0x3f, sizeof(f));
150+
for (int j : pos[key[0] - 'a']) {
151+
f[0][j] = min(j, n - j) + 1;
152+
}
153+
for (int i = 1; i < m; ++i) {
154+
for (int j : pos[key[i] - 'a']) {
155+
for (int k : pos[key[i - 1] - 'a']) {
156+
f[i][j] = min(f[i][j], f[i - 1][k] + min(abs(j - k), n - abs(j - k)) + 1);
157+
}
158+
}
159+
}
160+
int ans = 1 << 30;
161+
for (int j : pos[key[m - 1] - 'a']) {
162+
ans = min(ans, f[m - 1][j]);
163+
}
164+
return ans;
165+
}
166+
};
167+
```
76168
169+
### **Go**
170+
171+
```go
172+
func findRotateSteps(ring string, key string) int {
173+
m, n := len(key), len(ring)
174+
pos := [26][]int{}
175+
for j, c := range ring {
176+
pos[c-'a'] = append(pos[c-'a'], j)
177+
}
178+
f := make([][]int, m)
179+
for i := range f {
180+
f[i] = make([]int, n)
181+
for j := range f[i] {
182+
f[i][j] = 1 << 30
183+
}
184+
}
185+
for _, j := range pos[key[0]-'a'] {
186+
f[0][j] = min(j, n-j) + 1
187+
}
188+
for i := 1; i < m; i++ {
189+
for _, j := range pos[key[i]-'a'] {
190+
for _, k := range pos[key[i-1]-'a'] {
191+
f[i][j] = min(f[i][j], f[i-1][k]+min(abs(j-k), n-abs(j-k))+1)
192+
}
193+
}
194+
}
195+
ans := 1 << 30
196+
for _, j := range pos[key[m-1]-'a'] {
197+
ans = min(ans, f[m-1][j])
198+
}
199+
return ans
200+
}
201+
202+
func min(a, b int) int {
203+
if a < b {
204+
return a
205+
}
206+
return b
207+
}
208+
209+
func abs(x int) int {
210+
if x < 0 {
211+
return -x
212+
}
213+
return x
214+
}
77215
```
78216

79217
### **...**

Diff for: solution/0500-0599/0514.Freedom Trail/README_EN.md

+125-1
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,137 @@ So the final output is 4.
5353
### **Python3**
5454

5555
```python
56-
56+
class Solution:
57+
def findRotateSteps(self, ring: str, key: str) -> int:
58+
m, n = len(key), len(ring)
59+
pos = defaultdict(list)
60+
for i, c in enumerate(ring):
61+
pos[c].append(i)
62+
f = [[inf] * n for _ in range(m)]
63+
for j in pos[key[0]]:
64+
f[0][j] = min(j, n - j) + 1
65+
for i in range(1, m):
66+
for j in pos[key[i]]:
67+
for k in pos[key[i - 1]]:
68+
f[i][j] = min(
69+
f[i][j], f[i - 1][k] + min(abs(j - k), n - abs(j - k)) + 1
70+
)
71+
return min(f[-1][j] for j in pos[key[-1]])
5772
```
5873

5974
### **Java**
6075

6176
```java
77+
class Solution {
78+
public int findRotateSteps(String ring, String key) {
79+
int m = key.length(), n = ring.length();
80+
List<Integer>[] pos = new List[26];
81+
Arrays.setAll(pos, k -> new ArrayList<>());
82+
for (int i = 0; i < n; ++i) {
83+
int j = ring.charAt(i) - 'a';
84+
pos[j].add(i);
85+
}
86+
int[][] f = new int[m][n];
87+
for (var g : f) {
88+
Arrays.fill(g, 1 << 30);
89+
}
90+
for (int j : pos[key.charAt(0) - 'a']) {
91+
f[0][j] = Math.min(j, n - j) + 1;
92+
}
93+
for (int i = 1; i < m; ++i) {
94+
for (int j : pos[key.charAt(i) - 'a']) {
95+
for (int k : pos[key.charAt(i - 1) - 'a']) {
96+
f[i][j] = Math.min(f[i][j], f[i - 1][k] + Math.min(Math.abs(j - k), n - Math.abs(j - k)) + 1);
97+
}
98+
}
99+
}
100+
int ans = 1 << 30;
101+
for (int j : pos[key.charAt(m - 1) - 'a']) {
102+
ans = Math.min(ans, f[m - 1][j]);
103+
}
104+
return ans;
105+
}
106+
}
107+
```
108+
109+
### **C++**
110+
111+
```cpp
112+
class Solution {
113+
public:
114+
int findRotateSteps(string ring, string key) {
115+
int m = key.size(), n = ring.size();
116+
vector<int> pos[26];
117+
for (int j = 0; j < n; ++j) {
118+
pos[ring[j] - 'a'].push_back(j);
119+
}
120+
int f[m][n];
121+
memset(f, 0x3f, sizeof(f));
122+
for (int j : pos[key[0] - 'a']) {
123+
f[0][j] = min(j, n - j) + 1;
124+
}
125+
for (int i = 1; i < m; ++i) {
126+
for (int j : pos[key[i] - 'a']) {
127+
for (int k : pos[key[i - 1] - 'a']) {
128+
f[i][j] = min(f[i][j], f[i - 1][k] + min(abs(j - k), n - abs(j - k)) + 1);
129+
}
130+
}
131+
}
132+
int ans = 1 << 30;
133+
for (int j : pos[key[m - 1] - 'a']) {
134+
ans = min(ans, f[m - 1][j]);
135+
}
136+
return ans;
137+
}
138+
};
139+
```
62140
141+
### **Go**
142+
143+
```go
144+
func findRotateSteps(ring string, key string) int {
145+
m, n := len(key), len(ring)
146+
pos := [26][]int{}
147+
for j, c := range ring {
148+
pos[c-'a'] = append(pos[c-'a'], j)
149+
}
150+
f := make([][]int, m)
151+
for i := range f {
152+
f[i] = make([]int, n)
153+
for j := range f[i] {
154+
f[i][j] = 1 << 30
155+
}
156+
}
157+
for _, j := range pos[key[0]-'a'] {
158+
f[0][j] = min(j, n-j) + 1
159+
}
160+
for i := 1; i < m; i++ {
161+
for _, j := range pos[key[i]-'a'] {
162+
for _, k := range pos[key[i-1]-'a'] {
163+
f[i][j] = min(f[i][j], f[i-1][k]+min(abs(j-k), n-abs(j-k))+1)
164+
}
165+
}
166+
}
167+
ans := 1 << 30
168+
for _, j := range pos[key[m-1]-'a'] {
169+
ans = min(ans, f[m-1][j])
170+
}
171+
return ans
172+
}
173+
174+
func min(a, b int) int {
175+
if a < b {
176+
return a
177+
}
178+
return b
179+
}
180+
181+
func abs(x int) int {
182+
if x < 0 {
183+
return -x
184+
}
185+
return x
186+
}
63187
```
64188

65189
### **...**

Diff for: solution/0500-0599/0514.Freedom Trail/Solution.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
int findRotateSteps(string ring, string key) {
4+
int m = key.size(), n = ring.size();
5+
vector<int> pos[26];
6+
for (int j = 0; j < n; ++j) {
7+
pos[ring[j] - 'a'].push_back(j);
8+
}
9+
int f[m][n];
10+
memset(f, 0x3f, sizeof(f));
11+
for (int j : pos[key[0] - 'a']) {
12+
f[0][j] = min(j, n - j) + 1;
13+
}
14+
for (int i = 1; i < m; ++i) {
15+
for (int j : pos[key[i] - 'a']) {
16+
for (int k : pos[key[i - 1] - 'a']) {
17+
f[i][j] = min(f[i][j], f[i - 1][k] + min(abs(j - k), n - abs(j - k)) + 1);
18+
}
19+
}
20+
}
21+
int ans = 1 << 30;
22+
for (int j : pos[key[m - 1] - 'a']) {
23+
ans = min(ans, f[m - 1][j]);
24+
}
25+
return ans;
26+
}
27+
};

Diff for: solution/0500-0599/0514.Freedom Trail/Solution.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
func findRotateSteps(ring string, key string) int {
2+
m, n := len(key), len(ring)
3+
pos := [26][]int{}
4+
for j, c := range ring {
5+
pos[c-'a'] = append(pos[c-'a'], j)
6+
}
7+
f := make([][]int, m)
8+
for i := range f {
9+
f[i] = make([]int, n)
10+
for j := range f[i] {
11+
f[i][j] = 1 << 30
12+
}
13+
}
14+
for _, j := range pos[key[0]-'a'] {
15+
f[0][j] = min(j, n-j) + 1
16+
}
17+
for i := 1; i < m; i++ {
18+
for _, j := range pos[key[i]-'a'] {
19+
for _, k := range pos[key[i-1]-'a'] {
20+
f[i][j] = min(f[i][j], f[i-1][k]+min(abs(j-k), n-abs(j-k))+1)
21+
}
22+
}
23+
}
24+
ans := 1 << 30
25+
for _, j := range pos[key[m-1]-'a'] {
26+
ans = min(ans, f[m-1][j])
27+
}
28+
return ans
29+
}
30+
31+
func min(a, b int) int {
32+
if a < b {
33+
return a
34+
}
35+
return b
36+
}
37+
38+
func abs(x int) int {
39+
if x < 0 {
40+
return -x
41+
}
42+
return x
43+
}

0 commit comments

Comments
 (0)