牛客-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,对这道题还是没深入理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值