题目描述:

题目链接:最长公共子序列__牛客网

来源:牛客网

我们有两个字符串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]);}}
}

【编程题 动态规划】最长公共子序列(详细注释 易懂)相关推荐

  1. 最长公共子序列动态规划c语言,动态规划----最长公共子序列(C++实现)

    最长公共子序列 题目描述:给定两个字符串s1 s2 - sn和t1 t2 - tm .求出这两个字符串的最长公共子序列的长度.字符串s1 s2 - sn的子序列指可以表示为 - { i1 < i ...

  2. 动态规划——最长公共子序列(洛谷P1439)

    题目选自洛谷P1439 动态规划的模板题,最长公共子序列 1.譬如给定2个序列: 1 2 3 4 53 2 1 4 5 试求出最长的公共子序列. 那么 最普通的 LCS 代码: #include< ...

  3. LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品

    LeetCode高频题:最长公共子序列,玩游戏A和游戏B,两兄弟加起来最多可以获得多少奖品? 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面 ...

  4. 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence

    动态规划-最长公共子序列问题 Common Subsequence [ HDU - 1159 ] A subsequence of a given sequence is the given sequ ...

  5. 详解动态规划最长公共子序列--JavaScript实现

    前面两篇我们讲解了01背包问题和最少硬币找零问题.这篇将介绍另一个经典的动态规划问题--最长公共子序列.如果没看过前两篇,可点击下面链接. 详解动态规划最少硬币找零问题--JavaScript实现 详 ...

  6. 动态规划1--最长公共子序列

    动态规划1--最长公共子序列 一.动态规划 经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题.简单地采用把大问题分解成子问题,并 综合子问题的解导出大问题的解的方法,问题求解耗时 ...

  7. 牛客题霸 [最长公共子序列] C++题解/答案

    牛客题霸 [最长公共子序列] C++题解/答案 题目描述 给定两个字符串str1和str2,输出连个字符串的最长公共子序列.如过最长公共子序列为空,则输出-1. 题解: dp经典问题 代码: clas ...

  8. 最长公共子序列php,动态规划(最长公共子序列LCS)

    概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...

  9. zip()函数以及编程题:最长公共前缀(代码简单易懂)

    1.zip函数 zip()函数返回一个zip类型的对象,可以转换为list或dict #定义列表 a = [1, 2, 3] b = [4, 5, 6]# 打包为元组的列表,而且元素个数与最短的列表一 ...

  10. [Leetcode][第1143题][JAVA][最长公共子序列][LCS][动态规划]

    [问题描述][中等] [解答思路] 时间复杂度:O(N^2) 空间复杂度:O(N^2) class Solution {public int longestCommonSubsequence(Stri ...

最新文章

  1. 关于配置Bhuman通用平台环境心得
  2. HTML发布那一年,开发版内测公告一般发布时间是几点
  3. 【转载】在C#中运用SQLDMO备份和恢复Microsoft SQL Server数据库
  4. [读书笔记] - 《深度探索C++对象模型》第6章 第7章
  5. Python数据挖掘笔记 七 .PCA降维操作及subplot子图绘制
  6. word更新域后图片错误_你还不知道Word中F1~F12键作用?
  7. 人民日报:研究生期间该懂的47件事,你认可吗?
  8. git cherry-pick 多个commit_Git使用爬坑记录
  9. Atitit uke plnsy安全隐私保护法案 目录 第一章 一般规定 2 第1节 主题与目标 2 第二章 常见安全原则 3 第1节 隔离 保密 shell 3 第2节 隐藏 保密 不出头 3
  10. 计算机无法读取手机内存,手机sd卡无法读取,教您解决手机sd卡无法读取的方法...
  11. Charles使用笔记
  12. xp系统telnet服务器,xp电脑telnet服务器
  13. Win11如何获得最佳电源效率?
  14. oracle 按汉字拼音顺序排序
  15. Ubuntu firefox无法加载视频
  16. 2020,300道高级iOS开发面试题(最新整理)
  17. 成功解决: Windows10没有蓝牙问题
  18. 串之Ukkonen、Rabin_karp算法
  19. maya刷权重时有个叉_为什么maya刷权重 笔刷是打叉
  20. TDSQL PG 版企业级分布式数据库技术创新实践

热门文章

  1. 资深投资人全力反击: VC增值平台从来就不是一坨狗屎
  2. virtualbox出现failed to attach usb,VERR_PDM_NO_USB_PORTS问题解决
  3. python中seed的用法什么作用_Python中的seed()方法怎么用
  4. 节点表征学习与节点预测和边预测
  5. 【Redis 如何实现库存扣减操作】
  6. hevc_nvenc 详细分析2 ——preset分析
  7. 手机拍会议照片技巧_在家工作时进行视频会议的12个技巧
  8. Mysql-Cluster 集群部署
  9. 技术人员如何做晋升答辩
  10. mysql like json_Mysql之模糊查询