【算法】动态规划—最长公共子序列

news2024/9/22 1:15:59

        最长公共子序列问题就是求出两个字符串的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/2139512.html

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

相关文章

在线查看 Android 系统源代码 Git repositories on android

在线查看 Android 系统源代码 Git repositories on android 1. Git repositories on android1.1. Android Make Build System1.2. Android Open Source Project Code Review References 1. Git repositories on android https://android.googlesource.com/ 1.1. Android Make …

基于VUE的老年颐养中心系统的设计与实现计算机毕业论文

根据联合国的预测&#xff0c;2000-2050年将是我国人口年龄结构急剧老化的阶段&#xff0c;老化过程大致也可分为三个阶段&#xff1a;第一阶段&#xff0c;65岁及以上人口比例从2000年的6.97%上升到2020年的11.7%&#xff0c;20年时间仅上升4.63个百分点。第二阶段为2020-2040…

LVGL 控件之列表(lv_list)

目录 一、概述二、列表1、添加列表按钮2、设置列表文本3、API 函数 一、概述 List&#xff08;列表&#xff09; 基本上是一个垂直布局的矩形&#xff0c;按钮指向该矩形并且可以添加文本。 列表部件由两个部分组成&#xff1a; LV_PART_MAIN 使用所有典型背景属性的列表的主…

推荐|基于springBoot智能推荐的卫生健康系统设计与实现(源码+论文+数据库)

私信或留言即免费送开题报告和任务书&#xff08;可指定任意题目&#xff09; 目录 一、摘要 二、相关技 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取&#xff1a; 一、摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;…

打造下一个AI拥抱视频热潮:从CloneAI的成功中汲取灵感

在科技与创意的交汇点,CloneAI以其敏锐的洞察力和高效的执行力,在短时间内迅速崛起,成为App Store的明星应用。其成功不仅在于抓住了AI技术的浪潮,更在于精准地利用了社交媒体的趋势,创造了一个独特的用户体验。对于希望复刻这一成功的开发者们来说,CloneAI的经验无疑是一…

DolphinScheduler基础讲解

一、DolphinScheduler 概述 DolphinScheduler 是一个分布式、轻量级的大数据任务调度平台&#xff0c;旨在帮助企业高效管理和调度复杂的工作流。它通过图形化界面&#xff0c;简化了任务定义、依赖设置以及调度执行的过程&#xff0c;极大降低了用户上手的门槛。作为 Apache …

【homebrew安装】踩坑爬坑教程

homebrew官网&#xff0c;有安装教程提示&#xff0c;但是在实际安装时&#xff0c;由于待下载的包的尺寸过大&#xff0c;本地git缓存尺寸、超时时间的限制&#xff0c;会报如下错误&#xff1a; error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly&#xf…

Args4j:Java命令行参数解析的利器

在Java开发中&#xff0c;命令行工具的编写是一个常见的需求。如何高效、简洁地处理命令行参数&#xff0c;成为了提升开发效率和工具用户体验的关键。今天&#xff0c;我们将介绍一个强大的Java库——args4j&#xff0c;它专门用于简化命令行参数的解析过程。 文章目录 &#…

人工智能开发实战matplotlib库应用基础

内容导读 matplotlib简介绘制直方图绘制撒点图 一、matplotlib简介 matplotlib是一个Python 2D绘图库&#xff0c;它以多种硬拷贝格式和跨平台的交互式环境生成高质量的图形。 matplotlib 尝试使容易的事情变得更容易&#xff0c;使困难的事情变得可能。 我们只需几行代码…

拓扑排序专题篇

目录 前言 课程表 课程表II 课程表IV 火星词典 前言 拓扑排序是指对一个有向无环图的节点进行排序之后得到的序列&#xff0c;如果存在一条从节点A指向节点B的边&#xff0c;那么在拓扑排序的序列中节点A出现在节点B的前面。一个有向无环图可以有一个或多个拓扑排序序列&a…

QT Layout布局,隐藏其中的某些部件后,不影响原来的布局

最近在工作时&#xff0c;被要求&#xff0c;需要将布局中的某些部件隐藏后&#xff0c;但不能影响原来的布局。 现在记录解决方案&#xff01; 一、水平布局&#xff08;垂直布局一样&#xff09; ui中的布局 效果&#xff1a; 按钮可以任意隐藏&#xff0c;都不影响其中布…

基于双PI矢量控制结构和SVPWM的风力发电系统Simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PMSM数学模型 4.2 双PI控制结构 4.3 SVPWM 5.完整工程文件 1.课题概述 风力发电系统的核心是风力发电机&#xff0c;常见的有永磁同步发电机和感应发电机&#xff08;IG&#xff09;。这些发电机通…

XML_Tomcat_HTTP

第四章 XML_Tomcat10_HTTP 一 XML XML是EXtensible Markup Language的缩写&#xff0c;翻译过来就是可扩展标记语言。所以很明显&#xff0c;XML和HTML一样都是标记语言&#xff0c;也就是说它们的基本语法都是标签。 可扩展 三个字表面上的意思是XML允许自定义格式。但这不代…

用Python打造互动式中秋节庆祝小程序

中秋节&#xff0c;这个充满传统韵味的节日&#xff0c;不仅是家人团聚的时刻&#xff0c;也是程序员展示创意的好机会。本文将引导您使用Python创建一个互动式中秋节庆祝小程序&#xff0c;它不仅能够展示节日祝福&#xff0c;还能通过一些简单的特效增加节日气氛。 文章目录 …

python数据分析 pandas库-数据的读取和保存

python数据分析 pandas库-数据读取和保存 一、数据文件 在数据分析中&#xff0c;数据的读取是非常重要的一步。Pandas 提供了丰富的接口来读取各种格式的数据文件&#xff0c;例如 CSV、Excel、JSON、SQL 数据库等。接下来我们将详细说明如何使用 Pandas 读取不同格式的数据…

【人工智能学习笔记】6_自然语言处理基础

自然语言处理基本介绍 自然语言:指人类使用的在社会生活中自然形成的语言; 自然语言处理:指计算机识别、理解、计算分析、生成自然语言的过程。 包含自然语言理解和自然语言生成两部分的两大研究方向。 自然语言理解:所有支持机器理解文本内容的方法模型或任务的总称,是推…

代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用

代理IP批理检测工具,支持socks5,socks4,http和https代理批量检测是否可用 工具使用c编写&#xff1a; 支持ipv4及ipv6代理服务器。 支持http https socks4及socks5代理的批量检测。 支持所有windows版本运行&#xff01; 导入方式支持手工选择文件及拖放文件。 导入格式支持三…

常用游戏运行库下载

包含以下资源&#xff1a; DirectX Repair.exe DirectX Repair(Enhanced Edition). vcredist C2013 x64.exe 微软常用运行库合集 下载链接

Puppet 部署应用(Puppet deployment application)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

逻辑漏洞-其二(登录验证码安全)

2.登录验证码安全 验证码漏洞检测流程 2.1 图形验证码 无效验证 2.1.1 验证码可爆破 验证码可爆破&#xff0c;即验证码过于简单&#xff0c;例如验证码中字符数量过少&#xff0c;比如只有四位组成&#xff0c;且只包含 0-9 的数字还没有干扰点 &#xff0c;亦或者 验证码可以…