LCS—最长公共子序列

news2024/11/26 4:43:09

        最长公共子序列问题就是求出两个字符串的LCS长度,是一道非常经典的面试题目,因为它的解法是典型的二维动态规划。

        比如输入 str1 = "babcde", str2 = "acbe",算法应该输出3,因为 str1 和 str2 的最长公共子序列是 "ace",它的长度是3。

        子序列类型的问题,穷举出所有可能的结果都不容易,而动态规划算法做的就是穷尽+剪枝,它俩天生一对。所以可以说只要涉及子序列问题,十有八九需要动态规划来解决,往这方面考虑就对了。

动态规划思路

第一步,一定要明确dp数组的含义

        对于两个字符串的动态规划问题,套路都是通用的,一般都需要一个二维dp数组。比如对于字符串 str1 和 str2,一般来说要构造一个这样的 DP table:

        其中,dp[i][j]的含义是:对于 str1[0...i-1] 和 str2[0...j-1],它们的LCS长度是 dp[i][j]。

        上图这个例子,dp[2][4] = 2 的含义就是:对于 "ac" 和 "babc",它们的LCS长度是2。根据这个定义,最终想得到的答案应该是 dp[3][6]。

第二步,定义base case

        专门让索引为0的行和列表示空串,dp[0][..],dp[..][0]都应该初始化为0,这就是 base case。比如按照刚才dp数组的定义,dp[0][3]=0 的含义是:对于空字符串 "" 和 "bab",其LCS的长度为0。因为一个字符串是空串,它们的最长公共子序列的长度显然应该是0。

第三步,找状态转移方程

        很简单,做两种选择,要么在lcs中,要么不在。

        如果 str1[i] == str2[j],说明这个公共字符一定在lcs中。

        if str[i] == str[j]:

                dp(i, j) = dp(i-1, j-1) + 1

        如果 str1[i] != str2[j],说明 str[i] 和 str[j] 至少有一个不在lcs中,那么到底哪个字符不在lcs中?都试一下呗:

        if str1[i] != str2[j]:

                dp(i, j) = max(dp(i-1, j), dp(i, j-1))

第四步,直接写暴力解法

        首先写一个递归解法:

package DynamicProgramming;
// leetcode 095 最长公共子序列

// 暴力解法 (提交超出时间限制)
public class LCS {

    private String text1;
    private String text2;

    public int longestCommonSubsequence(String text1, String text2) {
        this.text1 = text1;
        this.text2 = text2;
        // 计算str1[0...i-1]和str2[0...j-1]中的lcs长度
        return dp(text1.length() - 1, text2.length() - 1);
    }

    public int dp(int i, int j) {
        // 递归终止条件
        // 空串的 base case
        if (i == -1 || j == -1) {
            return 0;
        }
        // 递归操作
        // 状态转移方程
        if (text1.charAt(i) == text2.charAt(j)) {
            // 这边找到一个lcs中的元素
            return dp(i - 1, j - 1) + 1;
        } else {
            // 至少有一个字符不在lcs中
            // 都试一下,谁能让lcs最长,就听谁的
            return Math.max(dp(i - 1, j), dp(i, j - 1));
        }
    }

    public static void main(String[] args) {
        LCS lcs = new LCS();
        int len = lcs.longestCommonSubsequence("babcde", "acbe");
        System.out.println(len);
    }

}

第五步,引入 DP table 来优化时间复杂度

// 引入dp table
public class LCS {

    public int longestCommonSubsequence(String text1, String text2) {
        // 1.定义dp table
        int m = text1.length();
        int n = text2.length();
        // 要算上表示空串的行列
        int[][] dp = new int[m + 1][n + 1];

        // 2.base case int型的数组默认值都是零,所以这一步可以没有

        // 3.状态转移方程
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; 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][j - 1], dp[i - 1][j]);
                }
            }
        }
        return dp[m][n];
    }

    public static void main(String[] args) {
        LCS lcs = new LCS();
        int len = lcs.longestCommonSubsequence("babcde", "acbe");
        System.out.println(len);
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2128862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何构建大数据治理平台,助力企业数据决策

建设背景 &#xff08;1&#xff09;什么是数据资产 资产由企业及组织拥有和控制&#xff0c;能够提供增值服务、带来经济利益的重要资源。 资产不但需要管理&#xff0c; 更需要运营。 &#xff08;2&#xff09;数据资产运营中的问题 数据资产运营中存在的问题主要包括以下…

【游戏杂谈】关于靠谱及不靠谱的游戏立项方式探讨

其他好内容推荐&#xff1a; 游戏二次创意算抄袭&#xff1f; - 游戏干饭之家 格斗游戏&#xff1a;一个伟大而古老的游戏类型 - 游戏干饭之家 游戏行业研究生和有两三年工作本科生谁更香&#xff1f; - 游戏干饭之家 立项一直是大部分公司和个人的难点&#xff0c;关于靠谱…

【MySQL】了解并操作MySQL的缓存配置与信息

目录 一、查看缓存配置 二、查看缓存信息 查询MySQL的缓存相关信息&#xff0c;一般我们用两个命令&#xff1a; show variables like %query_cache%; show status like %qcache%; 一、查看缓存配置 查看缓存配置的相关的系统变量变量&#xff0c;返回给我们服务器缓存的配置…

2024年危险化学品生产单位安全生产管理人员证考试题库及危险化学品生产单位安全生产管理人员试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品生产单位安全生产管理人员证考试题库及危险化学品生产单位安全生产管理人员试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&a…

cgdb对应vs中的调试代码——Linux代码调试

目录 打断点和删除断点&#xff1a; 删除断点&#xff1a; 运行代码&#xff1a;​编辑 监视&#xff1a; 补充&#xff1a;​编辑 对于程序员来说调试代码是个非常重要的工具&#xff0c;bug和调试类比孙悟空和如来&#xff0c;当我们打不过bug时就只能成为孙悟空口中的玉…

一层潮二层吵三层太低顶层又太高,挑到最后最后可选的只有:贵

1层太潮不想买&#xff0c;2层太吵不想要 3层嫌低&#xff0c;顶层怕高 带4的不好听&#xff0c;18层又晦气 剩下的楼层合心意&#xff0c;可就是钱包不乐意 如果真的有十全十美的房子 那唯一的缺点就是&#xff1a;贵&#xff01;贵&#xff01;&#xff01;贵&#xff0…

工商业光伏管理系统:提供16个流程全方位管理

为了确保光伏项目的顺利实施与高效运行&#xff0c;一套完善的工商业光伏管理系统显得尤为重要。该系统通过精细化的流程控制&#xff0c;覆盖了从初步沟通到并网运行的每一个环节&#xff0c;实现了项目的全方位管理。 一、初步沟通 在这一阶段&#xff0c;企业与光伏服务提供…

哨兵机制Sentinel

哨兵机制Sentinel 主从复制&#xff1a;读写分离&#xff0c;多读少写&#xff0c;单点故障&#xff08;主机宕机&#xff0c;从机不能自动切换&#xff09;&#xff0c;负载压力&#xff08;客户端请求&#xff0c;并发&#xff09;&#xff0c;数据集中存储&#xff08;主从…

k8s 容忍和污点

文章目录 Taint作用在节点上&#xff0c;能够使节点排斥一类特定的Pod&#xff0c;也就是不能“兼容”该节点的污点的Pod。对应的Toleration作用在Pod上&#xff0c;意为容忍&#xff0c;也就是可以兼容某类污点。 给节点增加一个Taint也很简单&#xff0c;直接使用kubectl ta…

Day23_0.1基础学习MATLAB学习小技巧总结(23)——句柄图形

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍&#xff0c;为了在这个过程中加深印象&#xff0c;也为了能够有所足迹&#xff0c;我会把自己的学习总结发在专栏中&#xff0c;以便学习交流。 参考书目&#xff1a;《MATLAB基础教程 (第三版) (薛山)》 之前的章节都是…

【区块链通用服务平台及组件】信息数据流转验真技术研究项目 | FISCO BCOS应用案例

在日常工作中&#xff0c;相关系统每天会产生大量数据&#xff0c;系统之间有多种模式数据交互方式&#xff0c;数据监管工作量巨大&#xff0c;急需 数据追溯定位工具来辅助监管&#xff1b;数据在生产过程中经常会出现采集、提交、修改、删除等操作&#xff0c;需要对数据变更…

【软件】Rhythmbox播放器调节音量

Rhythmbox播放器调节音量 零、起因 最近换了Ubuntu系统&#xff0c;在写代码时想听歌&#xff0c;故使用Rhythmbox播放器播放一些mp3文件&#xff0c;但同时又要看教程&#xff0c;希望音乐声音小一点&#xff0c;但是找来找去都没有发现Rhythmbox有调音量的地方&#xff0c;…

Linux 之 Nginx 下载/安装

下载 下载地址 nginx: download 安装 在线安装 配置新的yum源 # 切换到yum源目录 cd /etc/yum.repos.d/# 创建yum源文件 touch nginx.repo# 配置nginx.repo文件内容 vim nginx.reponginx.repo 文件内容 namenginx repo baseurlhttp://nginx.org/packages/centos/$releas…

Kubernetes从零到精通(08-工作负载-DaemonSet)

DaemonSet示例 DaemonSet是Kubernetes中的一种工作负载类型&#xff0c;专门用来确保集群中的每个&#xff08;或指定的&#xff09;节点上都运行一个Pod实例。它非常适用于需要在集群所有节点上提供服务的场景&#xff0c;比如日志收集、监控代理、或者网络插件。 以下是Daemo…

MS5612M_ 2.7V 到 5.5V、 12Bit、两通道数模转换器

产品简述 MS5612M 是一款 12bit 两通道输出的电压型 DAC &#xff0c;接口采用 三线串口模式&#xff0c;可以兼容 TMS320 、 SPI 、 QSPI 和 Microwire 串 口。 MS5612M 数据有 16bit &#xff0c;包括控制字节&#xff0c;和 12bitDAC 数据。 MS5612M 电源范围是 2.7V 到…

NIDS——suricata(一)

一、基于流量的入侵检测系统 1、基于主机的入侵检测系统——HIDS &#xff08;1&#xff09;功能 ①通过监控和分析系统日志、应用程序日志和安全日志来识别异常活动和潜在威胁。 ②通过跟踪分析系统上的命令执行和系统调用来检查是否存在恶意命令执行或不正常的系统操作。…

两个pdf合并成一个pdf,这些pdf合并小技巧了解下

在日常工作和学习中&#xff0c;我们经常会遇到需要将多个PDF文件合并成一个文件的情况。这不仅可以提高文件管理的效率&#xff0c;还能让信息展示更加集中和便捷。今天就来给大家分享几种非常简单便捷的PDF合并小技巧&#xff0c;一起来学习下吧。 方法一&#xff1a;WPS WP…

装杯 之 Linux 指令1

hello&#xff0c;欢迎来到linux世界&#xff0c;在害没有学习linux时&#xff0c;看到别人操作&#xff0c;网课&#xff0c;真高级&#xff0c;感觉好厉害&#xff0c;就是说白了&#xff0c;看起来牛逼。ok&#xff0c;接下来&#xff0c;请大佬们进入linux之旅。 1.ls指令…

Linux: network: esp:收到了重复的包?

最近遇到一个问题,是说收到了dup的ESP包,这是表象上的两个相同的ESP,那是因为在wireshark的首选项里IPv4,没有选择重组分片包,导致wireshark先做了ESP的解析,如果选择IPv4协议里的重组分片包,会看到下面说有三个分片,而且其中一个有overlap。 所以,这个目前还是未解的…

Debian项目实战——环境搭建篇

Debian系统安装 准备工作 1、系统镜像&#xff1a;根据自己的需要选择合适的版本格式&#xff1a;x86 / arm 架构 | 最好下载离线安装版本 | 清华镜像源 2、制作工具&#xff1a;balenaEtcher 3、系统媒介&#xff1a;16G以上U盘最佳 烧录镜像 打开balenaEtcher进行烧录&am…