牛客-NC92-最长公共子序列II

NC92. 最长公共子序列||(medium)


方法一:动态规划法

思路:这道题分两部分进行,首先是使用动态规划法求解LCS的长度,再逆序构建LCS。先说第一部分:定义一个二维dp数组 dp[i][j]:s1[0…i]和s2[0…j]为止的最长公共子序列的长度。
dp[0][0] = 0
dp[i][0] = 0
dp[0][j] = 0
dp[i][j] = dp[i - 1][j - 1] + 1, s1[i-1] == s2[j-1]
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]), s1[i-1] != s2[j-1]
可以写出以下代码:

public class NC92 {
   
    /** * longest common subsequence * @param s1 string字符串 the string * @param s2 string字符串 the string * @return string字符串 */
    public static String LCS (String s1, String s2) {
   
        // write code here
        char[] str1 = s1.toCharArray();
        char[] str2 = s2.toCharArray();
        int[][] dp = new int[str1.length + 1][str2.length + 1];
        for(int i = 0; i <= str1.length; i++) {
   
            for(int j = 0; j <= str2.length; j++) {
   
                if (i == 0 || j == 0) {
   
                    dp[i][j] = 0;
                    continue;
                }
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                if (str1[i - 1] == str2[j - 1]) {
   
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);
                }
            }
        }
        // 重构LCS
        int num = dp[str1.length][str2.length];
        //特判
        if (num == 0) return "-1";
        StringBuffer sb = new StringBuffer();
        int l1 = str1.length;
        int l2 = str2.length;
        while (l1 > 0 && l2 > 0) {
   
            if (s1.charAt(l1 - 1) == s2.charAt(l2 - 1)) {
   
                sb.append(s1.charAt(l1 - 1));
                l1 -= 1;
                l2 -= 1;
            } else {
   
                if (dp[l1 - 1][l2] > dp[l1][l2 - 1]) {
   
                    // 走上边
                    l1 -= 1;
                } else {
   
                    // 走左边
                    l2 -= 1;
                }
            }
        }
        return sb.reverse().toString();
    }

    public static void main(String[] args) {
   
        String s1 = "1A2C3D4B56";
        String s2 = "B1D23A456A";
        System.out.println(LCS(s1, s2));
    }
}

时间复杂度: O(MN),需要遍历s1和s2来填dp表。
空间复杂度: O(M
N),额外的dp表的空间。
总结:只知道怎么求LCS的长度,不知道怎么重构LCS,对这道题还是没深入理解。

全部评论

相关推荐

11-11 14:21
西京学院 C++
无敌混子大王:首先一点,不管学校层次怎么样,教育经历放在第一页靠上位置,第一页看不到教育经历,hr基本直接扔掉了
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务