# 2023-3-29 刷题情况

96 篇文章 2 订阅

## 最短公共超序列

### 代码实现

#### 暴力递归

class Solution {
public String shortestCommonSupersequence(String str1, String str2) {
if(str1.isEmpty()) return str2;
if(str2.isEmpty()) return str1;
var s1 = str1.substring(0, str1.length()-1);
var s2 = str2.substring(0, str2.length()-1);
var x = str1.charAt(str1.length()-1);
var y = str2.charAt(str2.length()-1);
if(x == y)
return shortestCommonSupersequence(s1, s2) + x;
var ans1 = shortestCommonSupersequence(s1, str2);
var ans2 = shortestCommonSupersequence(str1, s2);
if(ans1.length() < ans2.length())
return ans1 + x;
return ans2 + y;
}
}


#### 记忆化搜索

class Solution {
private String s, t;
private String[][] dir;

public String shortestCommonSupersequence(String str1, String str2) {
s = str1;
t = str2;
dir = new String[s.length()][t.length()];
return dfs(s.length() - 1, t.length() - 1);
}

private String dfs(int i, int j){
if(i < 0) return t.substring(0, j + 1);
if(j < 0) return s.substring(0, i + 1);
if(dir[i][j] != null) return dir[i][j];
if(s.charAt(i) == t.charAt(j))
return dir[i][j] = dfs(i - 1, j - 1) + s.charAt(i);
var ans1 = dfs(i - 1, j);
var ans2 = dfs(i, j - 1);
if(ans1.length() < ans2.length())
return dir[i][j] = ans1 + s.charAt(i);
return dir[i][j] = ans2 + t.charAt(j);
}
}


#### 优化后的记忆化

class Solution {
private String s, t;
private int[][] dir;

public String shortestCommonSupersequence(String str1, String str2) {
s = str1;
t = str2;
dir = new int[s.length()][t.length()];
dfs(s.length() - 1, t.length() - 1);
return answer(s.length() - 1, t.length() - 1);
}

private int dfs(int i, int j){
if(i < 0) return j + 1;
if(j < 0) return i + 1;
if(dir[i][j] > 0) return dir[i][j];
if(s.charAt(i) == t.charAt(j))
return dir[i][j] = dfs(i - 1, j - 1) + 1;
return dir[i][j] = Math.min(dfs(i-1, j), dfs(i, j-1)) + 1;
}

private String answer(int i, int j){
if(i < 0) return t.substring(0, j + 1);
if(j < 0) return s.substring(0, i + 1);
if(s.charAt(i) == t.charAt(j))
return answer(i - 1, j - 1) + s.charAt(i);
if(dfs(i, j - 1) < dfs(i - 1, j))
return answer(i, j - 1) + t.charAt(j);
return answer(i - 1, j) + s.charAt(i);
}
}


#### 动态规划（递推）

class Solution {
public String shortestCommonSupersequence(String str1, String str2) {
char[] s = str1.toCharArray();
char[] t = str2.toCharArray();
int n = s.length, m = t.length;
var f = new int[n + 1][m + 1];
// f[i][j]表示字符串 s 以 s[i] 为结尾，t 以 t[j] 结尾的最短公共超序列长度
for(int i = 1; i < m; i++) f[0][i] = i;
for(int i = 1; i < n; i++) f[i][0] = i;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(s[i] == t[j])
f[i + 1][j + 1] = f[i][j] + 1;
else
f[i+1][j+1] = Math.min(f[i+1][j], f[i][j+1]) + 1;

int mx = f[n][m];
var ans = new char[mx];
for(int i = n-1, j = m-1, k = mx-1; ; ){
if(i < 0){
System.arraycopy(t, 0, ans, 0, j + 1);
break;
}
if(j < 0){
System.arraycopy(s, 0, ans, 0, i + 1);
break;
}
if(s[i] == t[j]){
ans[k--] += s[i--];
j--;
}else if(f[i + 1][j + 1] == f[i][j + 1] + 1){
ans[k--] += s[i--];
}else{
ans[k--] += t[j--];
}
}
return new String(ans);
}
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
01-11 1007
01-29 399
02-21 288
01-24 398
02-05 233
02-15 256
03-11 1252
03-19 1853
04-07 5088
05-29 385

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。