Skip to content

Commit 369c416

Browse files
committed
feat: add solutions to lc problem: No.1092
No.1092.Shortest Common Supersequence
1 parent 8d02630 commit 369c416

File tree

6 files changed

+476
-2
lines changed

6 files changed

+476
-2
lines changed

solution/1000-1099/1092.Shortest Common Supersequence/README.md

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,196 @@ str2 = "cab" 是 "cabac" 的一个子串,因为我们可
3535

3636
<!-- 这里可写通用的实现逻辑 -->
3737

38+
**方法一:动态规划 + 构造**
39+
40+
我们先用动态规划求出两个字符串的最长公共子序列,然后根据最长公共子序列构造出最短公共超序列。
41+
42+
定义 $f[i][j]$ 表示字符串 $str1$ 的前 $i$ 个字符和字符串 $str2$ 的前 $j$ 个字符的最长公共子序列的长度。状态转移方程如下:
43+
44+
$$
45+
f[i][j] = \left\{\begin{matrix}
46+
0 & i = 0 \text{ or } j = 0 \\
47+
f[i - 1][j - 1] + 1 & str1[i - 1] = str2[j - 1] \\
48+
\max(f[i - 1][j], f[i][j - 1]) & str1[i - 1] \neq str2[j - 1]
49+
\end{matrix}\right.
50+
$$
51+
52+
接下来我们基于 $f[i][j]$ 构造出最短公共超序列。
53+
54+
用双指针 $i$ 和 $j$ 分别指向字符串 $str1$ 和 $str2$ 的末尾,然后从后往前遍历,每次比较 $str1[i]$ 和 $str2[j]$ 的值,如果 $str1[i] = str2[j]$,则将 $str1[i]$ 或 $str2[j]$ 中的任意一个字符加入到最短公共超序列的末尾,然后 $i$ 和 $j$ 同时减 1;如果 $str1[i] \neq str2[j]$,则将 $f[i][j]$ 与 $f[i - 1][j]$ 和 $f[i][j - 1]$ 中的最大值进行比较,如果 $f[i][j] = f[i - 1][j]$,则将 $str1[i]$ 加入到最短公共超序列的末尾,然后 $i$ 减 1;如果 $f[i][j] = f[i][j - 1]$,则将 $str2[j]$ 加入到最短公共超序列的末尾,然后 $j$ 减 1。重复上述操作,直到 $i = 0$ 或 $j = 0$,然后将剩余的字符串加入到最短公共超序列的末尾即可。
55+
56+
时间复杂度 $O(m\times n)$,空间复杂度 $O(m\times n)$。其中 $m$ 和 $n$ 分别是字符串 $str1$ 和 $str2$ 的长度。
57+
3858
<!-- tabs:start -->
3959

4060
### **Python3**
4161

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

4464
```python
45-
65+
class Solution:
66+
def shortestCommonSupersequence(self, str1: str, str2: str) -> str:
67+
m, n = len(str1), len(str2)
68+
f = [[0] * (n + 1) for _ in range(m + 1)]
69+
for i in range(1, m + 1):
70+
for j in range(1, n + 1):
71+
if str1[i - 1] == str2[j - 1]:
72+
f[i][j] = f[i - 1][j - 1] + 1
73+
else:
74+
f[i][j] = max(f[i - 1][j], f[i][j - 1])
75+
ans = []
76+
i, j = m, n
77+
while i or j:
78+
if i == 0:
79+
j -= 1
80+
ans.append(str2[j])
81+
elif j == 0:
82+
i -= 1
83+
ans.append(str1[i])
84+
else:
85+
if f[i][j] == f[i - 1][j]:
86+
i -= 1
87+
ans.append(str1[i])
88+
elif f[i][j] == f[i][j - 1]:
89+
j -= 1
90+
ans.append(str2[j])
91+
else:
92+
i, j = i - 1, j - 1
93+
ans.append(str1[i])
94+
return ''.join(ans[::-1])
4695
```
4796

4897
### **Java**
4998

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

52101
```java
102+
class Solution {
103+
public String shortestCommonSupersequence(String str1, String str2) {
104+
int m = str1.length(), n = str2.length();
105+
int[][] f = new int[m + 1][n + 1];
106+
for (int i = 1; i <= m; ++i) {
107+
for (int j = 1; j <= n; ++j) {
108+
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
109+
f[i][j] = f[i - 1][j - 1] + 1;
110+
} else {
111+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
112+
}
113+
}
114+
}
115+
int i = m, j = n;
116+
StringBuilder ans = new StringBuilder();
117+
while (i > 0 || j > 0) {
118+
if (i == 0) {
119+
ans.append(str2.charAt(--j));
120+
} else if (j == 0) {
121+
ans.append(str1.charAt(--i));
122+
} else {
123+
if (f[i][j] == f[i - 1][j]) {
124+
ans.append(str1.charAt(--i));
125+
} else if (f[i][j] == f[i][j - 1]) {
126+
ans.append(str2.charAt(--j));
127+
} else {
128+
ans.append(str1.charAt(--i));
129+
--j;
130+
}
131+
}
132+
}
133+
return ans.reverse().toString();
134+
}
135+
}
136+
```
137+
138+
### **C++**
139+
140+
```cpp
141+
class Solution {
142+
public:
143+
string shortestCommonSupersequence(string str1, string str2) {
144+
int m = str1.size(), n = str2.size();
145+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
146+
for (int i = 1; i <= m; ++i) {
147+
for (int j = 1; j <= n; ++j) {
148+
if (str1[i - 1] == str2[j - 1])
149+
f[i][j] = f[i - 1][j - 1] + 1;
150+
else
151+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
152+
}
153+
}
154+
int i = m, j = n;
155+
string ans;
156+
while (i || j) {
157+
if (i == 0)
158+
ans += str2[--j];
159+
else if (j == 0)
160+
ans += str1[--i];
161+
else {
162+
if (f[i][j] == f[i - 1][j])
163+
ans += str1[--i];
164+
else if (f[i][j] == f[i][j - 1])
165+
ans += str2[--j];
166+
else
167+
ans += str1[--i], --j;
168+
}
169+
}
170+
reverse(ans.begin(), ans.end());
171+
return ans;
172+
}
173+
};
174+
```
53175
176+
### **Go**
177+
178+
```go
179+
func shortestCommonSupersequence(str1 string, str2 string) string {
180+
m, n := len(str1), len(str2)
181+
f := make([][]int, m+1)
182+
for i := range f {
183+
f[i] = make([]int, n+1)
184+
}
185+
for i := 1; i <= m; i++ {
186+
for j := 1; j <= n; j++ {
187+
if str1[i-1] == str2[j-1] {
188+
f[i][j] = f[i-1][j-1] + 1
189+
} else {
190+
f[i][j] = max(f[i-1][j], f[i][j-1])
191+
}
192+
}
193+
}
194+
ans := []byte{}
195+
i, j := m, n
196+
for i > 0 || j > 0 {
197+
if i == 0 {
198+
j--
199+
ans = append(ans, str2[j])
200+
} else if j == 0 {
201+
i--
202+
ans = append(ans, str1[i])
203+
} else {
204+
if f[i][j] == f[i-1][j] {
205+
i--
206+
ans = append(ans, str1[i])
207+
} else if f[i][j] == f[i][j-1] {
208+
j--
209+
ans = append(ans, str2[j])
210+
} else {
211+
i, j = i-1, j-1
212+
ans = append(ans, str1[i])
213+
}
214+
}
215+
}
216+
for i, j = 0, len(ans)-1; i < j; i, j = i+1, j-1 {
217+
ans[i], ans[j] = ans[j], ans[i]
218+
}
219+
return string(ans)
220+
}
221+
222+
func max(a, b int) int {
223+
if a > b {
224+
return a
225+
}
226+
return b
227+
}
54228
```
55229

56230
### **...**

solution/1000-1099/1092.Shortest Common Supersequence/README_EN.md

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,167 @@ The answer provided is the shortest such string that satisfies these properties.
4242
### **Python3**
4343

4444
```python
45-
45+
class Solution:
46+
def shortestCommonSupersequence(self, str1: str, str2: str) -> str:
47+
m, n = len(str1), len(str2)
48+
f = [[0] * (n + 1) for _ in range(m + 1)]
49+
for i in range(1, m + 1):
50+
for j in range(1, n + 1):
51+
if str1[i - 1] == str2[j - 1]:
52+
f[i][j] = f[i - 1][j - 1] + 1
53+
else:
54+
f[i][j] = max(f[i - 1][j], f[i][j - 1])
55+
ans = []
56+
i, j = m, n
57+
while i or j:
58+
if i == 0:
59+
j -= 1
60+
ans.append(str2[j])
61+
elif j == 0:
62+
i -= 1
63+
ans.append(str1[i])
64+
else:
65+
if f[i][j] == f[i - 1][j]:
66+
i -= 1
67+
ans.append(str1[i])
68+
elif f[i][j] == f[i][j - 1]:
69+
j -= 1
70+
ans.append(str2[j])
71+
else:
72+
i, j = i - 1, j - 1
73+
ans.append(str1[i])
74+
return ''.join(ans[::-1])
4675
```
4776

4877
### **Java**
4978

5079
```java
80+
class Solution {
81+
public String shortestCommonSupersequence(String str1, String str2) {
82+
int m = str1.length(), n = str2.length();
83+
int[][] f = new int[m + 1][n + 1];
84+
for (int i = 1; i <= m; ++i) {
85+
for (int j = 1; j <= n; ++j) {
86+
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
87+
f[i][j] = f[i - 1][j - 1] + 1;
88+
} else {
89+
f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
90+
}
91+
}
92+
}
93+
int i = m, j = n;
94+
StringBuilder ans = new StringBuilder();
95+
while (i > 0 || j > 0) {
96+
if (i == 0) {
97+
ans.append(str2.charAt(--j));
98+
} else if (j == 0) {
99+
ans.append(str1.charAt(--i));
100+
} else {
101+
if (f[i][j] == f[i - 1][j]) {
102+
ans.append(str1.charAt(--i));
103+
} else if (f[i][j] == f[i][j - 1]) {
104+
ans.append(str2.charAt(--j));
105+
} else {
106+
ans.append(str1.charAt(--i));
107+
--j;
108+
}
109+
}
110+
}
111+
return ans.reverse().toString();
112+
}
113+
}
114+
```
115+
116+
### **C++**
117+
118+
```cpp
119+
class Solution {
120+
public:
121+
string shortestCommonSupersequence(string str1, string str2) {
122+
int m = str1.size(), n = str2.size();
123+
vector<vector<int>> f(m + 1, vector<int>(n + 1));
124+
for (int i = 1; i <= m; ++i) {
125+
for (int j = 1; j <= n; ++j) {
126+
if (str1[i - 1] == str2[j - 1])
127+
f[i][j] = f[i - 1][j - 1] + 1;
128+
else
129+
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
130+
}
131+
}
132+
int i = m, j = n;
133+
string ans;
134+
while (i || j) {
135+
if (i == 0)
136+
ans += str2[--j];
137+
else if (j == 0)
138+
ans += str1[--i];
139+
else {
140+
if (f[i][j] == f[i - 1][j])
141+
ans += str1[--i];
142+
else if (f[i][j] == f[i][j - 1])
143+
ans += str2[--j];
144+
else
145+
ans += str1[--i], --j;
146+
}
147+
}
148+
reverse(ans.begin(), ans.end());
149+
return ans;
150+
}
151+
};
152+
```
51153
154+
### **Go**
155+
156+
```go
157+
func shortestCommonSupersequence(str1 string, str2 string) string {
158+
m, n := len(str1), len(str2)
159+
f := make([][]int, m+1)
160+
for i := range f {
161+
f[i] = make([]int, n+1)
162+
}
163+
for i := 1; i <= m; i++ {
164+
for j := 1; j <= n; j++ {
165+
if str1[i-1] == str2[j-1] {
166+
f[i][j] = f[i-1][j-1] + 1
167+
} else {
168+
f[i][j] = max(f[i-1][j], f[i][j-1])
169+
}
170+
}
171+
}
172+
ans := []byte{}
173+
i, j := m, n
174+
for i > 0 || j > 0 {
175+
if i == 0 {
176+
j--
177+
ans = append(ans, str2[j])
178+
} else if j == 0 {
179+
i--
180+
ans = append(ans, str1[i])
181+
} else {
182+
if f[i][j] == f[i-1][j] {
183+
i--
184+
ans = append(ans, str1[i])
185+
} else if f[i][j] == f[i][j-1] {
186+
j--
187+
ans = append(ans, str2[j])
188+
} else {
189+
i, j = i-1, j-1
190+
ans = append(ans, str1[i])
191+
}
192+
}
193+
}
194+
for i, j = 0, len(ans)-1; i < j; i, j = i+1, j-1 {
195+
ans[i], ans[j] = ans[j], ans[i]
196+
}
197+
return string(ans)
198+
}
199+
200+
func max(a, b int) int {
201+
if a > b {
202+
return a
203+
}
204+
return b
205+
}
52206
```
53207

54208
### **...**

0 commit comments

Comments
 (0)