力扣1143-最长公共子序列(Java详细题解)

题目链接:1143. 最长公共子序列 - 力扣(LeetCode)

前情提要:

如果你做过718. 最长重复子数组 - 力扣(LeetCode)并且看过我的这篇题解力扣718-最长重复子数组(Java详细题解)-CSDN博客,那么做这道题会简单很多。

因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。

dp五部曲。

1.确定dp数组和i下标的含义。

2.确定递推公式。

3.dp初始化。

4.确定dp的遍历顺序。

5.如果没有ac打印dp数组 利于debug。

每一个dp题目如果都用这五步分析清楚,那么这道题就能解出来了。

题目思路:

本题是要求俩个字符串的最长公共子序列的长度。注意这里的子序列和力扣718. 最长重复子数组的子序列不一样,本题的子序列是可以不连续的,而最长重复子数组是需要连续的。

话不多说,直接开始我们的dp五部曲。

1.确定dp数组和i下标的含义。

dp[i] [j]的含义是以i - 1结尾的字符串与j - 1结尾的字符串最长公共子序列的长度。

至于为什么是i- 1和j - 1大家可以看看这篇力扣718-最长重复子数组(Java详细题解)-CSDN博客

2.确定递推公式。

本题就难在递推公式。

因为我们要求最长公共子序列,可以是不连续的。

所以主要是俩大情况。一个是nums[i - 1] == nums[j - 1],

另一个就是不等于的情况。

当nums[i - 1] == nums[j - 1]时,说明此时结尾的元素相等,那么此时的最长公共子序列就等于他前一个状态加上相同元素的长度即可.

dp[i] [j] = dp[i - 1] [j - 1] + 1。

当nums[i - 1] != nums[j - 1]时,说明此时结尾的元素不等,那么此时我们就需要删除俩个数组中的最后一位元素。我们需要删除哪一个数组呢?

不知道,但是我们是要求最长的公共子序列的长度,所以我们取一个最大即可。

dp[i] [j] = Math.max(dp[i] [j - 1],dp[i - 1] [j]);

3.dp初始化。

由递推公式可以看出,最长公共子序列不仅由它左上的方向推出还可以由它左和上的方向推出。

所以第一排和第一列是递推的起点,我们就要初始化第一排和第一列。

因为dp[i] [0]和dp[0] [i]是将一个没有意义的字符串和另一个字符串求最长公共子序列,所以他们的长度就为0。

4.确定dp的遍历顺序。

由递推公式可以得出最长公共子序列不仅由它左上的方向推出还可以由它左和上的方向推出。

所以我们的遍历顺序是从左到右,从上到下。

5.如果没有ac打印dp数组 利于debug。

最终代码:

java 复制代码
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int [][] dp = new int [text1.length() + 1][text2.length() + 1];
        int result = 0;
        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)){
                    //这里与最长重复子数组有一点区别 因为子数组是一种连续的结构 只要有一个不同 那么就不算重复的
                    //但是子序列不同 只要是在某一个界限前 一样的都算
                    //所以这里有俩种情况 当text1.charAt(i - 1) == text2.charAt(j - 1)时 那么就该把长度加一 俩个前一位的最长的公共子序列然后加1
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                }//如果不同 也有可能是有公共子序列的 比如 abc 与 ace 虽然最后一位不同 但他们是最长子序列为2
                //所以我们可以把拿abc以c结尾的字符串和ace以c为结尾字符串做对比
                //同理也可以拿abc以b为结尾的字符串与ace以e为结尾字符串做对比
                //抽象就是 最长公共子序列不仅由它左上的方向推出还可以由它左和上的方向推出
                else{
                    dp[i][j] = Math.max(dp[i - 1][j],dp[i][j - 1]);
                }text1.length()
                //这里顺便记录一下最长公共子序列的最大长度 其实也可以不用记录 返回dp[text1.length()][text2.length()]也可以
                    //因为本题所有的dp数组都会更新
                result = Math.max(result,dp[i][j]);
            }
        }
        return result;
    }
}

这一篇博客就到这了,如果你有什么疑问和想法可以打在评论区,或者私信我。

我很乐意为你解答。那么我们下篇再见!

相关推荐
m0_5719575829 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
pianmian13 小时前
python数据结构基础(7)
数据结构·算法
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
好奇龙猫5 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
sp_fyf_20245 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘