Java最长公共子序列示例源码

Java最长公共子序列示例源码可以用于找到两个字符串之间的最长公共子序列。以下是Java最长公共子序列示例源码的完整攻略:

1. 题目描述

给定两个字符串s1s2,找到它们的最长公共子序列(LCS)。

2. 示例

示例1:

输入:s1 = "abcde", s2 = "ace" 
输出:3  
解释:最长公共子序列是 "ace",它的长度是3。

示例2:

输入:s1 = "abc", s2 = "abc"
输出:3
解释:最长公共子序列是 "abc",它的长度是3。

3. 解法分析

在这个问题中,我们可以使用动态规划的方法来解决。

如果我们定义一个二维数组dp[i][j]来表示s1s2中前i个和前j个字符的LCS长度,那么我们可以考虑以下几种情况:

  1. 如果s1[i-1]s2[j-1]相同,那么它们肯定在LCS中。此时,dp[i][j] = dp[i-1][j-1] + 1
  2. 如果s1[i-1]s2[j-1]不同,则它们可能不在LCS中,此时我们需要选择跳过s1[i-1]或者s2[j-1],哪种选择能让LCS最长,就选哪种。因此,dp[i][j] = max(dp[i-1][j], dp[i][j-1])

最终,dp[s1.length()][s2.length()]表示的就是s1s2的LCS长度。

4. 代码实现

public int longestCommonSubsequence(String s1, String s2) {
    int m = s1.length(), n = s2.length();
    int[][] dp = new int[m + 1][n + 1];
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1.charAt(i - 1) == s2.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[m][n];
}

5. 示例说明

示例1

输入的两个字符串是 "abcde""ace"。我们使用二维数组dp来表示它们之间的LCS长度。

初始化的时候,dp[0][0]表示空字符串的LCS长度为0,那么 dp[0][j]dp[i][0] 也必须都为0,因此 dp 数组的第一行和第一列都初始化为0。

  a   c   e
a 0   0   0
b 0   0   0
c 0   1   1
d 0   1   1
e 0   1   2

我们可以看到,当s1[i-1]s2[j-1]相同时,dp[i][j] = dp[i-1][j-1] + 1;当s1[i-1]s2[j-1]不同时,dp[i][j] = max(dp[i-1][j], dp[i][j-1])

因此在初始化后的dp数组中,例如dp[3][1]s1[2]s2[0]不同,则它们可能不在LCS中,此时我们需要选择跳过s1[2]或者s2[0],哪种选择能让LCS最长,就选哪种。: dp[3][1] = max(dp[2][1], dp[3][0]) = max(1, 0) = 1

最终dp[s1.length()][s2.length()]的值就是3,即s1s2的LCS长度。

示例2

输入的两个字符串是 "abc""abc"

初始化的时候,dp[0][0]表示空字符串的LCS长度为0,那么 dp[0][j]dp[i][0] 也必须都为0,因此 dp 数组的第一行和第一列都初始化为0。

  a   b   c
a 0   0   0
b 0   1   1
c 0   1   2

同样的,我们可以看到,当s1[i-1]s2[j-1]相同时,dp[i][j] = dp[i-1][j-1] + 1;当s1[i-1]s2[j-1]不同时,dp[i][j] = max(dp[i-1][j], dp[i][j-1])

因此最终dp[s1.length()][s2.length()]的值就是3,即s1s2的LCS长度。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java最长公共子序列示例源码 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • MyBatis动态SQL标签用法实例详解

    MyBatis动态SQL标签用法实例详解 本文介绍了MyBatis中动态SQL标签的用法及示例。动态SQL标签允许我们根据不同的条件动态生成SQL语句,让SQL语句变得更加灵活和通用。下面分别介绍了if、choose、foreach、when、otherwise五种常用的动态SQL标签。 if标签 if标签可以根据条件判断是否要拼接SQL语句。示例代码如下:…

    Java 2023年5月20日
    00
  • 正则表达式中的反向预搜索(上)

    当我们使用正则表达式时,有时候我们需要匹配的内容在某些条件下才成立,这时候就可以使用反向预搜索(lookbehind)来实现。反向预搜索是指在匹配字符时,先查找指定的字符后面是否满足一定的条件,如果满足再继续匹配。 反向预搜索有两种形式:正向零宽度断言(positive lookbehind)和负向零宽度断言(negative lookbehind)。正向零…

    Java 2023年5月23日
    00
  • SpringBoot创建多模块项目的全过程记录

    我将为您详细讲解如何使用SpringBoot创建多模块项目的全过程记录。创建多模块项目有很多好处,例如可以将不同的功能模块独立开发、测试和维护,增加代码的可读性和可维护性。下面是创建多模块项目的步骤: 1. 创建maven的多模块工程 使用Maven创建一个新的多模块项目,一个工程包含多个子模块。在项目的根目录下,使用以下Maven命令创建一个多模块项目: …

    Java 2023年6月15日
    00
  • Java的Struts框架报错“NoSuchSubscriptionException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“NoSuchSubscriptionException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置,则可能会出现此。在这种情况下,需要检查文件以解决此问题。 订阅名称错误:如果订阅名称不正确,则可能出现此。在这种情况下,需要检查订阅名称以解决此问题。 以下是两个实例: 例 1 如…

    Java 2023年5月5日
    00
  • Java多线程的实现方式比较(两种方式比较)

    Java多线程是Java程序中常见的高级特性,使用多线程可以让程序同时执行多个任务,提高程序的效率。Java中多线程的实现方式主要有两种,一种是继承Thread类,一种是实现Runnable接口。下面我们来详细讲解这两种实现方式的比较。 继承Thread类的实现方式 继承Thread类是Java中自带多线程的一种实现方式,需要创建一个继承自Thread类的类…

    Java 2023年5月18日
    00
  • 详解Java MyBatis 插入数据库返回主键

    下面是详解Java MyBatis 插入数据库返回主键的攻略。 一、前置条件 在讲解插入数据库返回主键之前,需要先了解以下几个前置条件: 数据库主键必须是自增长的,例如MySQL的AUTO_INCREMENT。 数据库引擎必须支持返回主键,例如MySQL的InnoDB引擎支持。 二、具体实现 1.使用MyBatis的insert方法返回主键 MyBatis提…

    Java 2023年5月20日
    00
  • 一文掌握Spring Boot 日志文件

    一文掌握 Spring Boot 日志文件 在 Spring Boot 应用中,日志文件是非常重要的一部分,它可以帮助我们实时监控应用运行过程中发生的错误和异常,同时也便于开发人员分析问题并进行调试。本文将分享如何使用 Spring Boot 内置的日志框架 Logback 来配置日志文件。 添加 Logback 依赖 首先,在项目的 pom.xml 文件中…

    Java 2023年5月19日
    00
  • Java下载文件的四种方式详细代码

    下面我将为您详细讲解Java下载文件的四种方式和完整代码。 一、使用Java自带的URL类进行文件下载 使用Java自带的URL类可以方便地进行文件下载,步骤如下: 创建一个URL对象,指定需要下载的文件链接。 打开 URL 连接,获取 InputStream 对象,用于读取远程文件流。 创建文件输出流对象,用于保存下载的文件。 读取远程文件并将其写入到本地…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部