【编程题 动态规划】最长公共子序列(详细注释 易懂)
题目描述:
题目链接:最长公共子序列__牛客网
来源:牛客网
我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度。
输入描述:
输入包含多组数据。每组数据包含两个字符串m和n,它们仅包含字母,并且长度不超过1024。
输出描述:
对应每组输入,输出最长公共子序列的长度。
示例1
输入
abcfbc abfcab programming contest abcd mnp
输出
4 2 0
思路讲解: (动态规划)
要求从两个字符串中,找到最长的子序列,这两个子序列不一定是连续的。 以题目中这两个字符串举例, abcfbc abfcab ,公共子序列有 a,ab,abc,af ,abcb等,但最长的只有abcb,我们通过肉眼能很容易的看出来,abcb是符合题意的最长公共子序列,找出这个子序列,我们潜意识的排除了 顺序不对的公共项(就是没有把 abcf 和 abfc 视为符合题意的子序列),排除了字符比较时,相同的字符被重复计算的问题, 也没有因为中间有间隔,就把abc 视为最长公共子序列。
但程序中要让它排除这些问题, 常规的方法很麻烦而且很难,于是我们采用 动规思想,就是让一个字符串中的每一个字符去 和 另一个字符串中的每一个字符进行比较,如果相同就给次数加 一 ? 不,这样就会出现我前面提到的问题,相同的字符被重复比较,比如 abcfbc 中的 字符 a 在与 abfcab 比较时,会被计算两次。那为了避免这个问题,我们就看它们的前一位,在它们前一位的基础上进行加一。 具体看下图,再进一步解释。
根据图来继续进行讲解,因为不能两个字符一相等,就给公共子序列个数加一,我们要看它们的前面一个,所以为了在第一个字符进行比较时有所参考,我们给要比较的两个字符串前面加一个空字符,空字符和谁比较都是0,这里没有问题吧。
然后具体讲解这个记录两个字符比较的二维数组(arr[ ][ ])如何进行。 还是以 abfcab 和 abcfbc为例, 刚开始用 abfcab 的 a字符 和 abcfbc 的每一个字符进行比较,和它里面的a相同,先看它们的前面一位,都是空,也就是arr[0][0] =0 (初始化后默认为0) ,那么此刻的公共子序列长度为 0+1 =1, 然后继续用 a 比较abcfbc 里的 b,不相同,不相同就看 a前面的空字符与 abcfbc 的ab比较结果是0, 再看 a与 abcfbc 中b前面的字符(也就是a)比较结果是1, 所以 abfcab 中的a 与 abcfbc 中的b 公共字符串长度应该是1(取两者的最大值),因为abfcab 中的a 与 abcfbc 中的b(其实是ab)确实有一个相同的字符。 abfcab 中的a 继续与 abcfbc 中的 c,f,b,c 比较结果都是1。
然后,abfcab 中的 b 与 abcfbc 每一个字符进行比较, 比到b时,看它们前一位 也就是arr[1][1] 是1,所以此时的公共子序列长度为 1+1 =2 ,然后继续比较 比到 abcfbc 的第二个b时,看它们的前面一个 也就是arr[1][4], 结果是1,所以这里的公共子序列是2,而不是3。 为什么总要看前一个,因为 abfcab 中b 的前一个是a ,a与 abcfbc整个比较完也确实只有一个相等(这里不要误解,a与 abcbaaa 比较也只有一个相等)。
我们通过看前一个,就能避免重复的问题。 所以这样就能得到,大家看着有点头疼的 动规规划状态方程,
若str1[ i ] == str2[ j ],则 arr[ i ][ j ] = max( dp[ i-1 ][ j ], dp[ i ][ j-1 ], dp[ i-1 ][ j-1 ]+1 )
若str1[ i ] != str2[ j ],则 dp[ i ][ j ] = max( dp[ i-1 ][ j ], dp[ i ][ j-1 ] )
现在看它,应该好理解多了吧 !
代码解释
// write your code here
import java.util.*;
public class Main{public static void main(String[] args){Scanner scan = new Scanner(System.in);while(scan.hasNext()){String m = scan.next();String n =scan.next();int lenM = m.length();int lenN = n.length();// 我们需要给字符串前面加空格,便于后面的字符串比较,所以大小设为 lenM+1和lenN+1 int[][] arr = new int[lenM+1][lenN+1];for(int i=1;i<= lenM;i++){for(int j=1;j<= lenN;j++){// 依次比较两个字符串的每一个字符,但要注意是字符串,要用charAt()函数获取每个字符if(m.charAt(i-1)== n.charAt(j-1)){// 这里就是运用上面的状态方程arr[i][j]= arr[i-1][j-1]+1;}else{arr[i][j]=Math.max(arr[i-1][j],arr[i][j-1]);}}}// 最后为什么要打印这个值,有上面图可以看出 比较结果为4 的位置有多个, 这里是因为,只有arr[lenM][lenN]处的数值,才能代表是两个字符串wan'zhen System.out.println(arr[lenM][lenN]);}}
}
【编程题 动态规划】最长公共子序列(详细注释 易懂)相关推荐
- 最长公共子序列动态规划c语言,动态规划----最长公共子序列(C++实现)
最长公共子序列 题目描述:给定两个字符串s1 s2 - sn和t1 t2 - tm .求出这两个字符串的最长公共子序列的长度.字符串s1 s2 - sn的子序列指可以表示为 - { i1 < i ...
- 动态规划——最长公共子序列(洛谷P1439)
题目选自洛谷P1439 动态规划的模板题,最长公共子序列 1.譬如给定2个序列: 1 2 3 4 53 2 1 4 5 试求出最长的公共子序列. 那么 最普通的 LCS 代码: #include< ...
- LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品
LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品? 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面 ...
- 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence
动态规划-最长公共子序列问题 Common Subsequence [ HDU - 1159 ] A subsequence of a given sequence is the given sequ ...
- 详解动态规划最长公共子序列--JavaScript实现
前面两篇我们讲解了01背包问题和最少硬币找零问题.这篇将介绍另一个经典的动态规划问题--最长公共子序列.如果没看过前两篇,可点击下面链接. 详解动态规划最少硬币找零问题--JavaScript实现 详 ...
- 动态规划1--最长公共子序列
动态规划1--最长公共子序列 一.动态规划 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并 综合子问题的解导出大问题的解的方法,问题求解耗时 ...
- 牛客题霸 [最长公共子序列] C++题解/答案
牛客题霸 [最长公共子序列] C++题解/答案 题目描述 给定两个字符串str1和str2,输出连个字符串的最长公共子序列.如过最长公共子序列为空,则输出-1. 题解: dp经典问题 代码: clas ...
- 最长公共子序列php,动态规划(最长公共子序列LCS)
概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...
- zip()函数以及编程题:最长公共前缀(代码简单易懂)
1.zip函数 zip()函数返回一个zip类型的对象,可以转换为list或dict #定义列表 a = [1, 2, 3] b = [4, 5, 6]# 打包为元组的列表,而且元素个数与最短的列表一 ...
- [Leetcode][第1143题][JAVA][最长公共子序列][LCS][动态规划]
[问题描述][中等] [解答思路] 时间复杂度:O(N^2) 空间复杂度:O(N^2) class Solution {public int longestCommonSubsequence(Stri ...
最新文章
- 关于配置Bhuman通用平台环境心得
- HTML发布那一年,开发版内测公告一般发布时间是几点
- 【转载】在C#中运用SQLDMO备份和恢复Microsoft SQL Server数据库
- [读书笔记] - 《深度探索C++对象模型》第6章 第7章
- Python数据挖掘笔记 七 .PCA降维操作及subplot子图绘制
- word更新域后图片错误_你还不知道Word中F1~F12键作用?
- 人民日报:研究生期间该懂的47件事,你认可吗?
- git cherry-pick 多个commit_Git使用爬坑记录
- Atitit uke plnsy安全隐私保护法案 目录 第一章 一般规定	2 第1节 主题与目标	2 第二章 常见安全原则	3 第1节 隔离 保密 shell	3 第2节 隐藏 保密 不出头	3
- 计算机无法读取手机内存,手机sd卡无法读取,教您解决手机sd卡无法读取的方法...
- Charles使用笔记
- xp系统telnet服务器,xp电脑telnet服务器
- Win11如何获得最佳电源效率?
- oracle 按汉字拼音顺序排序
- Ubuntu firefox无法加载视频
- 2020,300道高级iOS开发面试题(最新整理)
- 成功解决: Windows10没有蓝牙问题
- 串之Ukkonen、Rabin_karp算法
- maya刷权重时有个叉_为什么maya刷权重 笔刷是打叉
- TDSQL PG 版企业级分布式数据库技术创新实践
热门文章
- 资深投资人全力反击: VC增值平台从来就不是一坨狗屎
- virtualbox出现failed to attach usb,VERR_PDM_NO_USB_PORTS问题解决
- python中seed的用法什么作用_Python中的seed()方法怎么用
- 节点表征学习与节点预测和边预测
- 【Redis 如何实现库存扣减操作】
- hevc_nvenc 详细分析2 ——preset分析
- 手机拍会议照片技巧_在家工作时进行视频会议的12个技巧
- Mysql-Cluster 集群部署
- 技术人员如何做晋升答辩
- mysql like json_Mysql之模糊查询