最长公共子序列问题
最长公共子序列:
给定一个序列X={x1,x2,x3...xm},另一个序列Z={z1,z2,z3...zk}满足如下条件时称为X的子序列,即存在一个严格递增的X的下标序列<i1,i2...ik>对所有j=1,2...k满足xi=zj。给定两个序列X,Y,如果既是X的子序列又是Y的子序列,那就称为X,Y的公共子序列。最长公共子序列就是所有子序列中最长的一个或几个。
用动态规划法来解最长公共子序列问题:
1.刻画最长公共子序列的特征
令X={x1,x2,x3...xm},Y={y1,y2,y3...yn},Z={z1,z2,z3...zk}是X,Y的公共子序列。
LCS的最优子结构为:
1.if xm==yn 则zk==xm==yn且zk-1是xm-1,yn-1的LCS
2. if xm != yn 那么zk!=xm意味着Z是xm-1和Y的LCS
3.if xm != yn 那么zk!=yn意味着Z是X和yn-1的LCS
2.递归解
定义c[i][j表示Xi和YjLCS长度,有如下公式:
0 i==0 || j==0
c[i][j] = c[i-1][j-1]+1 i,j>0&&xi==yj
max(c[i][j-1], c[i-1][j]) i,j>0&&xi!=yj
3.计算LCS长度
用b[i][j]来保存子问题的最优解
伪码:(算法导论)
c[i][j]和吧b[i][j]的跟踪
4.构造LCS
伪码:
实现代码:
package dp_lcs; /** *最长公共子序列 *@author wxisme *@time 2015-10-22 下午4:49:44 */ public class Solve_LCS { public static char[] x; public static char[] y; public static int[][] c; //c[i][j]表示xi,yj的lcs public static int[][] b; //记录最优值 /** * 计算LCS */ public static void lcs_length() { int m = x.length+1; int n = y.length+1; c = new int[m][n]; b = new int[m][n]; for(int i=0; i<m; i++) c[i][0] = 0; for(int j=0; j<n; j++) c[0][j] = 0; for(int i=1; i<m; i++) { for(int j=1; j<n; j++) { if(x[i-1] == y[j-1]) { 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] = 2; //上 } else { c[i][j] = c[i][j-1]; b[i][j] = 3; //左 } } } } /** * 构造LCS * @param i * @param j */ public static void print_LCS(int i, int j) { if(i==0 || j==0) return ; if(b[i][j] == 1) { print_LCS(i-1, j-1); System.out.print(x[i-1]); } else if(b[i][j] == 2) { print_LCS(i-1, j); } else { print_LCS(i, j-1); } } }
测试数据:
public static void main(String[] args) { Solve_LCS ret = new Solve_LCS(); x = new char[]{'A', 'B', 'C', 'B', 'D', 'A', 'B'}; y = new char[]{'B', 'D', 'C', 'A', 'B', 'A'}; ret.lcs_length(); ret.print_LCS(x.length, y.length); }
结果:
1 | BCBA |
参考算法导论第三版
作者:Pickle
声明:对于转载分享我是没有意见的,出于对博客园社区和作者的尊重一定要保留原文地址哈。
致读者:坚持写博客不容易,写高质量博客更难,我也在不断的学习和进步,希望和所有同路人一道用技术来改变生活。觉得有点用就点个赞哈。








【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战