LeetCode 最长公共子序列 Java 动态规划 有图解

题目描述

给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

例如

"ace""abcde" 的子序列,但 "aec" 不是 
"abcde" 的子序列。两个字符串的「公共子序列」
是这两个字符串所共同拥有的子序列。

若这两个字符串没有公共子序列,则返回 0。

示例 1:

输入:text1 = "abcde", text2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace",它的长度为 3

示例 2:

输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc",它的长度为 3

示例 3:

输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0

提示:

1 <= text1.length <= 1000
1 <= text2.length <= 1000
输入的字符串只含有小写英文字符。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:DP
怎么DP呢,题目要什么我们设什么,既然是两个字符串我们就设一个二维数组dp[i][j],表示第一个字符的前i个字符和第二个字符的前j个字符所能构成的最长子序列,由样例可知子序列是可以不连续的,因此最长的肯定dp[t1.length][t2.length]
然后我们再来看最后一步,

1.if t1.charAt(t1.length-1)和t2.charAt(t2.length-1)不相等;
我们要怎么办?直接等于dp[t1.length-1-1][t2.length-1-1]?不对,因为这个子序列是可以不连续的,来画个图:最后一个长度不相等的时候

说是不包含两者中的至少一个,为什么没有都不包含 即dp[i-1][j-1]呢?在状态转移方程中添加进去其实可以,也能得到正确答案,但没必要,因为 dp[i-1][j-1] 肯定是 小于等于dp[i][j-1],dp[i-1][j], max 根本不可能取到它,i和j越大,它所可能包含到的相同的回文串就越多,纸上画一下就很清楚了,我懒就不画了哈哈哈哈

2.相等的情况下,就直接dp[i][j]=dp[i-1][j-1]+1;这个应该很好理解
然后上代码:

class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
            char s1[]=text1.toCharArray();
            char s2[]=text2.toCharArray();
            int x=s1.length;
            int y=s2.length;
            int dp[][]=new int[x+1][y+1];
            for(int i=1;i<=x;i++){
                for(int j=1;j<=y;j++){
                    if(s1[i-1]==s2[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[x][y];
    }
}
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页