频道栏目
首页 > 资讯 > C++ > 正文

DP4 最长公共子序列 LCS @geeksforgeeks

13-12-24        来源:[db:作者]  
收藏   我要投稿

 

LCS Problem Statement: Given two sequences, find the length of longest subsequence present in both of them. A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous. For example, “abc”, “abg”, “bdf”, “aeg”, ‘”acefg”, .. etc are subsequences of “abcdefg”. So a string of length n has 2^n different possible subsequences.

It is a classic computer science problem, the basis of diff (a file comparison program that outputs the differences between two files), and has applications in bioinformatics.

Examples:
LCS for input Sequences “ABCDGH” and “AEDFHR” is “ADH” of length 3.
LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.

The naive solution for this problem is to generate all subsequences of both given sequences and find the longest matching subsequence. This solution is exponential in term of time complexity. Let us see how this problem possesses both important properties of a Dynamic Programming (DP) Problem.

1) Optimal Substructure:
Let the input sequences be X[0..m-1] and Y[0..n-1] of lengths m and n respectively. And let L(X[0..m-1], Y[0..n-1]) be the length of LCS of the two sequences X and Y. Following is the recursive definition of L(X[0..m-1], Y[0..n-1]).

If last characters of both sequences match (or X[m-1] == Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = 1 + L(X[0..m-2], Y[0..n-2])

If last characters of both sequences do not match (or X[m-1] != Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = MAX ( L(X[0..m-2], Y[0..n-1]), L(X[0..m-1], Y[0..n-2])

Examples:
1) Consider the input strings “AGGTAB” and “GXTXAYB”. Last characters match for the strings. So length of LCS can be written as:
L(“AGGTAB”, “GXTXAYB”) = 1 + L(“AGGTA”, “GXTXAY”)

2) Consider the input strings “ABCDGH” and “AEDFHR. Last characters do not match for the strings. So length of LCS can be written as:
L(“ABCDGH”, “AEDFHR”) = MAX ( L(“ABCDG”, “AEDFHR”), L(“ABCDGH”, “AEDFH”) )

So the LCS problem has optimal substructure property as the main problem can be solved using solutions to subproblems.

2) Overlapping Subproblems:
Following is simple recursive implementation of the LCS problem. The implementation simply follows the recursive structure mentioned above.


 

package DP;

import java.util.Arrays;

// 最长公共子串 Longest Common Subsequence
public class LCS {

	static int dp[][] = null;
	
	public static void main(String[] args) {
		String a = AGGTAB;
		String b = GXTXAYB;
		
		dp = new int[a.length()+1][b.length()+1];
		for(int[] row : dp){
			Arrays.fill(row, -1);
		}
		
		System.out.println(lcs2(a.toCharArray(), a.length(), b.toCharArray(), b.length()));
		System.out.println(lcs3(a.toCharArray(), a.length(), b.toCharArray(), b.length()));
//		print();
		System.out.println(lcs(a.toCharArray(), a.length(), b.toCharArray(), b.length()));
		
	}

	/* A Naive recursive implementation of LCS problem */
	// 纯递归O(m*2^n)
	public static int lcs(char[] A, int m, char[] B, int n){
		if(m==0 || n==0){
			return 0;
		}
		
		if(A[m-1] == B[n-1]){
			return 1 + lcs(A, m-1, B, n-1);
		}else{
			return Math.max(lcs(A, m, B, n-1), lcs(A, m-1, B, n));
		}
	}
	
	// DP, top-down O(n^2)
	public static int lcs2(char[] A, int m, char[] B, int n){
		if(m==0 || n==0){
			return 0;
		}
		
		// 如果已经存在dp数组中,直接返回
		if(dp[m][n] != -1){
			return dp[m][n];
		}
		int res = 0;
		if(A[m-1] == B[n-1]){
			res = 1 + lcs2(A, m-1, B, n-1);
		}else{
			res = Math.max(lcs2(A, m, B, n-1), lcs2(A, m-1, B, n));
		}
		dp[m][n] = res;		// 把新值记录到dp数组中
		return res;
	}
	
	// DP, bottom-up O(n^2)
	public static int lcs3(char[] A, int m, char[] B, int n){
		for(int i=0; i<=m; i++){
			for(int j=0; j<=n; j++){
				if(i==0 || j==0){
					dp[i][j] = 0;
				}
				else if(A[i-1] == B[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]);
				}
			}
		}
		return dp[m][n];
	}
	
	public static void print(){
		for(int i=0; i

 

相关TAG标签
上一篇:[leetcode]Same Tree (比较两棵二叉树是否相同)
下一篇:Delphi - 无边无状态栏窗口
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站