JAVA程序设计:最短公共超序列(LeetCode: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 <= str1.length, str2.length <= 1000
str1 和 str2 都由小写英文字母组成。

思路:最长公共子序列变形题,我们知道答案分三部分,分别为公共部分、str1独有的部分和str2独有的部分。我们通过最长公共子序列的做法预处理出两个串最长公共子序列,然后按顺序添加这三个部分即可。

class Solution {
    public String shortestCommonSupersequence(String str1, String str2) {

        int n = str1.length();
        int m = str2.length();
        String[][] dp = new String[n + 1][m + 1];

        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                dp[i][j] = "";

        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] + "" + str1.charAt(i - 1);
                else
                    dp[i][j] = dp[i - 1][j].length() > dp[i][j - 1].length() ? dp[i - 1][j] : dp[i][j - 1];
            }

        int i = 0, j = 0;
        char[] c_list = dp[n][m].toCharArray();
        StringBuilder ans = new StringBuilder();

        for (char c : c_list) {
            while (i < n && str1.charAt(i) != c)
                ans.append(str1.charAt(i++));
            while (j < m && str2.charAt(j) != c)
                ans.append(str2.charAt(j++));
            if (i < n) ans.append(str1.charAt(i));
            i++; j++;
        }

        while (i < n) ans.append(str1.charAt(i++));
        while (j < m) ans.append(str2.charAt(j++));

        return ans.toString();

    }
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值