动态规划--3.最长公共子序列LCS和最长公共子字符串
来源:互联网 发布:机器人 毛笔字 算法 编辑:程序博客网 时间:2024/06/01 15:20
1.LCS:序列X{x1,x2,x3...xm}和序列Y{y1,y2...yn}找到两个序列的最长公共子序列是指X中的某些元素按照先后顺序出现在Y中,比如x1和x2出现在Y中,一定要x1在前x2在后,但二者可以不连续。 再比如BDCABA 和 ABCBDAB,字符串 BCBA 和 BDAB 都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子序列。
2.理解题意后我们设C[i,j]表示序列 x1,x2...xi 和序列 y1,y2...yn 的最长公共子序列,此处 i 和 j 分别为X Y最后元素的下标,那么:
(1)当i=0 || j=0时, C[i,j]=0
(2)当 xi=yj时,C[i,j]=C[i-1,j-1] +1; 即两个序列最后一个元素都相等时,那么子序列=两个元素加入之前的情况+1
(3)当xi != yj 时,C[i,j]=max{ C[i-1,j] , C[i,j-1] }; 即当两个序列最后一个元素不等时,子序列=只加入Xi 不加入yj 和只加入yj 不加入xi的情况中的最大值
3. 动态规划的时间复杂度=子问题的个数*每个子问题选择的种数,在lcsLength函数中时间复杂度为O(mn),在print函数中采用递归形式,时间复杂度为O(m+n)
/** * */package lcs;/** * @author LingLee *动态规划 最长公共子序列问题 * */public class LCS {public static int[][] lcsLength(String x,String y){int[][] c=new int[x.length()][y.length()];//c[i][j]是用来记录序列x1...xi和序列y1...yn最长公共子序列的长度的int[][] b=new int[x.length()][y.length()];//b[i][j]记录表中走向的for(int i=0;i<x.length();i++) c[i][0]=0;for(int j=0;j<y.length();j++) c[0][j]=0;for(int i=1;i<x.length();i++){for(int j=1;j<y.length();j++){if(x.charAt(i)==y.charAt(j)){//当xi=yj时c[i][j]=c[i-1][j-1]+1;b[i][j]=1;//往左上角走}else if(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];b[i][j]=0;//往上走,或者说是往j的那一面走}else{c[i][j]=c[i][j-1];b[i][j]=-1;//往左走,或者说往靠近i的那一面走}}}System.out.println("最长公共子序列长度="+c[x.length()-1][y.length()-1]);return b;}public static void print(int[][] b,String x,int i,int j){if(i==0||j==0) return;if(b[i][j]==1){print(b,x,i-1,j-1);System.out.print(x.charAt(i)+"\t");}else if(b[i][j]==0){print(b,x,i-1,j);}else{print(b,x,i,j-1);}}public static void main(String[] args){String x=" ABCBDAB";//注意i和j是从1开始的,所以字符串的首个字符并没有参与比较String y=" BDCABA";int [][] b=lcsLength(x,y);print(b,x,x.length()-1,y.length()-1);}}
public class LCS { public int findLCS(String s1, int n, String s2, int m) { // write code here int[][] dp=new int[n][m];//n*m列 //初始化 boolean temp=false; for(int i=0;i<n;i++){//注意初始化部分,s[i]与s2[0]相等,那么i之后的所有子序列与s2[0]的公共子序列都是s[0] if(s1.charAt(i)==s2.charAt(0)){ temp=true; } if(temp) dp[i][0]=1; else dp[i][0]=0; } temp=false; for(int i=0;i<m;i++){ if(s2.charAt(i)==s1.charAt(0)) temp=true; if(temp) dp[0][i]=1; else dp[0][i]=0; } for(int i=1;i<n;i++){ for(int j=1;j<m;j++){ if(s1.charAt(i)==s2.charAt(j)) { 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[n-1][m-1]; }}
二、最长公共子字符串
1.该问题和lcs唯一的不同是,公共子字符串要求元素字符按照先后顺序出现且是连续的。再比如BDCABA 和 ABCBDAB,最长公共子字符串为AB
0 0
- 动态规划--3.最长公共子序列LCS和最长公共子字符串
- 【动态规划】最长公共子序列LCS
- 动态规划---LCS最长公共子序列
- 动态规划-最长公共子序列【LCS】
- 动态规划-最长公共子序列(LCS)
- 动态规划-LCS最长公共子序列
- 动态规划----最长公共子序列LCS
- (动态规划)LCS-最长公共子序列
- 动态规划 最长公共子序列LCS
- LCS(最长公共子序列)和dp(动态规划)
- 动态规划之LCS最长公共子序列和最长公共子串
- 最长回文子序列:字符串反转+动态规划,最长公共子序列LCS算法
- 动态规划 最长公共子序列LCS、最长公共连续子串、最长重复子串
- 最长公共子序列LCS和最长回文子序列的动态规划算法
- 动态规划解决最长公共子序列和最长公共子字符串问题 java实现
- 动态规划--最长公共子序列和公共子串
- 动态规划实现最长公共子序列(LCS)算法
- 动态规划之最长公共子序列(lcs)
- jquery multi-select 简单用法的备份
- 使用js制作滑动条
- Android启动后,加载的2类service (Native 系统Service, Java 系统Service)
- Java String关于indexof方法区分大小写的一个小贴士
- 子序列的和
- 动态规划--3.最长公共子序列LCS和最长公共子字符串
- 设计模式:模板方法
- 【Android 进阶】Android 按键事件简单理解
- 题目1010:A + B
- SpringMVC学习(十)之转发与重定向
- 给PE文件增加可执行代码
- maven阿里云中央仓库
- Git设置忽略排除和重新添加已经被忽略过文件(夹)的方法
- Java day3