最长公共子序列

AcWing 897. 最长公共子序列

给定两个长度分别为 NN 和 MM 的字符串 AA 和 BB,求既是 AA 的子序列又是 BB 的子序列的字符串长度最长是多少。
输入格式
第一行包含两个整数 NN 和 MM。
第二行包含一个长度为 NN 的字符串,表示字符串 AA。
第三行包含一个长度为 MM 的字符串,表示字符串 BB。
字符串均由小写字母构成。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N,M≤10001≤N,M≤1000
输入样例:
4 5
acbd
abedc
输出样例:
3

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int n = sc.nextInt(), m = sc.nextInt();
  6. String s1 = sc.next(), s2 = sc.next();
  7. int[][] f = new int[n + 1][m + 1];
  8. for (int i = 1; i <= n; i++) {
  9. char c1 = s1.charAt(i - 1);
  10. for (int j = 1; j <= m; j++) {
  11. char c2 = s2.charAt(j - 1);
  12. f[i][j] = Math.max(f[i][j-1], f[i-1][j]);
  13. if (c1 == c2)
  14. f[i][j] = Math.max(f[i][j], f[i-1][j-1] + 1);
  15. }
  16. }
  17. System.out.println(f[n][m]);
  18. }
  19. }

1092. 最短公共超序列

给出两个字符串 str1 和 str2,返回同时以 str1 和 str2 作为子序列的最短字符串。如果答案不止一个,则可以返回满足条件的任意一个答案。
(如果从字符串 T 中删除一些字符(也可能不删除,并且选出的这些字符可以位于 T 中的 任意位置),可以得到字符串 S,那么 S 就是 T 的子序列)

示例:
输入:str1 = “abac”, str2 = “cab” 输出:“cabac” 解释: str1 = “abac” 是 “cabac” 的一个子串,因为我们可以删去 “cabac” 的第一个 “c”得到 “abac”。 str2 = “cab” 是 “cabac” 的一个子串,因为我们可以删去 “cabac” 末尾的 “ac” 得到 “cab”。 最终我们给出的答案是满足上述属性的最短字符串。

提示:

  1. 1 <= str1.length, str2.length <= 1000
  2. str1 和 str2 都由小写英文字母组成。

思路:
涉及了LCS求具体方案

  1. class Solution {
  2. public String shortestCommonSupersequence(String s1, String s2) {
  3. int n = s1.length(), m = s2.length();
  4. int[][] f = new int[n + 1][m + 1];
  5. for (int i = 1; i <= n; i++) {
  6. char c1 = s1.charAt(i - 1);
  7. for (int j = 1; j <= m; j++) {
  8. char c2 = s2.charAt(j - 1);
  9. if (c1 == c2)
  10. f[i][j] = f[i - 1][j - 1] + 1;
  11. f[i][j] = Math.max(f[i][j], Math.max(f[i - 1][j], f[i][j - 1]));
  12. }
  13. }
  14. int x = n, y = m;
  15. StringBuilder sb = new StringBuilder();
  16. while (x > 0 || y > 0) {
  17. if (x == 0) {
  18. sb.append(s2.charAt(y - 1));
  19. y--;
  20. } else if (y == 0) {
  21. sb.append(s1.charAt(x - 1));
  22. x--;
  23. } else {
  24. if (s1.charAt(x - 1) == s2.charAt(y - 1)) {
  25. sb.append(s1.charAt(x - 1));
  26. x--;
  27. y--;
  28. } else {
  29. if (f[x][y - 1] == f[x][y]) {
  30. sb.append(s2.charAt(y - 1));
  31. y--;
  32. } else {
  33. sb.append(s1.charAt(x - 1));
  34. x--;
  35. }
  36. }
  37. }
  38. }
  39. return sb.reverse().toString();
  40. }
  41. }