java 最长公共子序列(LSC)问题
来源:互联网 发布:淘宝店铺全套免费模板 编辑:程序博客网 时间:2024/06/05 23:06
题目:
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)
举例:
思路:
这道题连暴力求解的欲望都没有,如果不用动态规划来做,暴力求解的时间级要到指数级别。那么对于这道题的思路,我们先用dp求出子序列状态数组,再通过求得的数组用回溯法得到一个最长子序列。
第一步:用动态规划求出状态数组
状态定义:
二维数组Fi,j表示两个字符串在前i和j长的子串中最长子序列情况。求Fn,m中最大值。
状态转移方程:
在Str1.charAt(i) == Str2.charAt(j)时,有 Fi,j=Fi-1,j-1+1
在Str1.charAt(i) ! = Str2.charAt(j)时,有 Fi,j=max{Fi-1,j,Fi,j-1}
第二步:使用回溯法得到一个最长子序列的解
回溯法:
第一种方法:从i=n,j=m(右下角)开始,一直到i=0,j=0(左上角)时完成回溯。
第二种方法:将dp[n][m]的值赋予count,每次输出字符count自减,当count减小至0时完成回溯。
题解:
import java.io.PrintWriter;import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); PrintWriter out = new PrintWriter(System.out); String aStr = in.nextLine(); String bStr = in.nextLine(); int aLen = aStr.length(); int bLen = bStr.length(); int[][] dp = new int[aLen + 1][bLen + 1]; StringBuilder sb = new StringBuilder(); for (int i = 1; i < aLen + 1; i++) for (int j = 1; j < bLen + 1; j++) if (aStr.charAt(i - 1) == bStr.charAt(j - 1)) dp[i][j] = dp[i - 1][j-1] + 1; else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); int max = dp[aLen][bLen]; while (max > 0) { if (dp[aLen - 1][bLen] == dp[aLen][bLen - 1] && dp[aLen - 1][bLen] + 1 == dp[aLen][bLen]) { sb.append(aStr.charAt(aLen - 1)); max--; aLen--; bLen--; } else { if (dp[aLen][bLen - 1] == dp[aLen][bLen]) bLen--; else aLen--; } } out.println(sb.reverse().toString()); }}
这道题之所以可以用dp来求解就是因为它存在最优子序列,我们可以使用递推的方式来得到答案,对于每一个斜对角所包含的四个数组中的元素,都存在状态转移方程。需要注意的是,一般的dp只要先确定了第一个点的数据就可以确定其他位置的数据,而我们的LSC代码中并不需要这样做,我们在分配数组时,为左侧额外分配了一行一列的空间,这样的好处是显而易见的——省去了边界判断的麻烦。对于回溯法,我们的思路是判断当前所在的元素的左边和上边是不是相等且为该元素值减1,如果满足条件说明我们到了当前元素值的“边界”,当前元素的横纵坐标代表的字符是相同的,我们输出到StringBuilder中,然后直接将位置移动到左上角,如果不满足刚才的条件则将当前位置左移或者上移至相同数组处。这是搜索整个数组最快的方法。
- java 最长公共子序列(LSC)问题
- LSC 最长公共序列
- 最长公共子序列问题-求所有公共子序列(java核心代码实现)
- 最长公共子序列问题(Java)-动态规划
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS问题)
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- poj1458(最长公共子序列问题)
- 最长公共子序列(LCS)问题
- 最长公共子序列(LCS)问题
- 最长公共子序列问题(LCS)
- 79. Word Search
- Servlet 监听器----ServletRequest
- 五大常用算法之三:贪心算法
- 一些实用网站
- 文章标题
- java 最长公共子序列(LSC)问题
- [译]图像分类:数据驱动方法、K-最近邻、train/val/test分离 (2)
- Educational Codeforces Round 26 E. Vasya's Function 数学,迭代法
- 如何修改Tomcat服务器Server Locations
- Android Studio 2.2 更方便地创建JNI项目-CMake
- howto prevent a process from terminating when writing to a broken pipe
- poj 2796 单调栈
- hdu 4609 3-idiots(FFT)
- 用jspf文件做jsp页面的通用页面头