leetcode 1143. 最长公共子序列

难度:中等
频次:64

**题目:**给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

  • 例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
    两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
    leetcode 1143. 最长公共子序列_第1张图片
    解题思路:动态规划
    注意:
  • 为什么是动态规划?—>求最值,并且都跟前面的值有关。并且之前求过最长有序子串就是用的动态规划
  • 这里的起始值 是dp[0][1] dp[0][1] dp[0][0]都等于0,代表的意思就是只要出现一个空字符串,最后的最值都为0
  • 两个for循环都是从1开始的,并且dp[i][j]代表的是第一个字符串的前i个和第二个字符串的前j个的最长公共子串,i和j的取值是从0-n和0-m(n、m分别表示两个字符串的长度)
  • 两个转移转移方程
    • 第一个条件是最后的两个元素相等 dp[i][j]=d[i-1][j-1]+1;
    • 第二个条件是最后的两个元素不相等 那么就把一个拆成两个求解,并且取大值。
      dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1])

代码:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int n=text1.length(),m=text2.length();
        //new int 需要注意,并且我们dp是从1开始的
        //为什么是从1开始的?很多人说这样子比较方便
        //但实际上是由状态转移方程决定的,因为跟之前的有关。所以这里必须长度多1个,再加上我们思维是从1开始的
        int[][] dp=new int[n+1][m+1];//dp[i][j] 代表的是第一个长度为i,第二个长度为j的最长公共子串长度
        //这里的最初状态其实时dp[1][0]=0, dp[1][0]这里就不写了
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                //状态转移方程主要有两条
                if(text1.charAt(i-1)==text2.charAt(j-1)){
                    //如果最后两个元素相等,那么整体的dp=去掉相等元素的dp值+1
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    //如果不不相等,就把一个拆成2个求解,最后取两个里的最大值即可
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[n][m];
    }
}

你可能感兴趣的:(leetcode刷题本,leetcode,动态规划,算法)