codeTop100题(34)1143. 最长公共子序列

92 阅读1分钟

1. 题目

1143. 最长公共子序列

2. 分析

看题目是一个二维动态规划的题目:

  1. 首先需要确定dp数组的含义:字符串a 0-i的子串 和 字符串b0-j的 最长子序列长度;

  2. 然后推导递推公式:

  • 当字符串a和b在i j位置的字符相同的时候,最长子序列为i-1,j-1 的最大长度+1

image.png

  • 当字符串a和b在i j位置的字符不相同的时候,最长子序列为i,j-1 和 i-1,j 直接的最大值

image.png

image.png

  1. 初始化值 当字符串a 和 b为空字符串的时候,最长子序列的长度为0。

  2. 遍历顺序

要达到递推公式的条件,我们需要两层遍历,从字符串a 0-i做一层变量,字符串b0-j第二层遍历

3. 代码

public int longestCommonSubsequence(String text1, String text2) {
    //dp数组表示字符串a 0-i的子串 和 字符串b0-j的 最长子序列长度
    //当a的i位置和b的j位置相等
    //dp[i][j] = dp[i-1][j-1] + 1;
    //当a的i位置和b的j位置不相等的时候
    //dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
    //初始化,当a b子串长度为0时,最长子序列为0

    int[][] dp = new int[text1.length() + 1][text2.length() + 1];
    for (int i = 1; i <= text1.length(); i++) {
        for (int j = 1; j <= text2.length(); j++) {
            if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                dp[i][j] = dp[i-1][j-1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
            }
        }
    }
    return dp[text1.length()][text2.length()];
}