1092. 最短公共超序列
给出两个字符串 str1 和 str2,返回同时以 str1 和 str2 作为子序列的最短字符串。如果答案不止一个,则可以返回满足条件的任意一个答案。
(如果从字符串 T 中删除一些字符(也可能不删除,并且选出的这些字符可以位于 T 中的 任意位置),可以得到字符串 S,那么 S 就是 T 的子序列)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-common-supersequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.Scanner;
class Solution {
public String shortestCommonSupersequence(String str1, String str2) {
if (str1 == null || str1.length() == 0 || str2 == null || str2.length() == 0) {
return "";
}
/**
* 最长公共子序列
*/
int n = str1.length(), m = str2.length();
int[][] dp = new int[n + 1][m + 1];
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
/**
* 逆推得到最长公共子序列
*/
StringBuilder sb = new StringBuilder();
int x = n, y = m;
while (x >= 1 && y >= 1) {
if (str1.charAt(x - 1) == str2.charAt(y - 1)) {
sb.append(str1.charAt(x - 1));
x--;
y--;
} else {
if (dp[x][y - 1] > dp[x - 1][y]) {
y--;
} else {
x--;
}
}
}
sb = sb.reverse();
StringBuilder ret = new StringBuilder();
int idx1 = 0, idx2 = 0, idx3 = 0;
while (idx3 < sb.length()) {
while (str1.charAt(idx1) != sb.charAt(idx3)) {
ret.append(str1.charAt(idx1++));
}
while (str2.charAt(idx2) != sb.charAt(idx3)) {
ret.append(str2.charAt(idx2++));
}
idx1++;
idx2++;
ret.append(sb.charAt(idx3++));
}
ret.append(str1.substring(idx1)).append(str2.substring(idx2));
return ret.toString();
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
System.out.println(new Solution().shortestCommonSupersequence(in.next(), in.next()));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号