012-算法面试必备-LCS问题(longest Common SubString)

 * 最长公共子序列LCS问题
 * Longest common squence
 * 两个字符串对应的Index相同的部分一致,才算是相似的公共子序列

 * 给出两个字符串S1和S2,求这两个字符串的最长公共子序列的长度

 采用递归和动态规划的方式进行,同时打印出来最长的字符串

//采用递归的方法进行求解最长公共子序列,然后求出最长公共子序列的长度,
//同时获取最长的公共子序列
class Solution_LongestCommonSequence0713{
	private int[][] memo;  //递归+采用记忆化搜索
	private int getLength(String s1,String s2,int n,int m){  //这里的n,m代表了索引
		if(n == -1 || m == -1)return 0;
		if(memo[n][m] != -1) return memo[n][m];
		int maxLength = 0;
		if(s1.charAt(n) == s2.charAt(m)){
			maxLength = getLength(s1,s2,n-1,m-1) + 1;
		}else{
//			maxLength = Math.max(maxLength,getLength(s1,s2,n-1,m));
			maxLength = Math.max(getLength(s1,s2,n-1,m),getLength(s1,s2,n,m-1));
		}
		memo[n][m] = maxLength;
		return maxLength;
		
	}
	public int getMaxLength(String s1,String s2){
		int n = s1.length();
		int m = s2.length();
		memo = new int[n][m];
		for(int i = 0;i<n;i++){
			Arrays.fill(memo[i],-1);
		}
		return getLength(s1,s2,n-1,m-1);	
	}
	public int getmaxLengthDy(String s1,String s2){
		int n = s1.length();
		int m = s2.length();
		if(n == 0||m == 0)return 0;
		int[][] memo = new int[n][m]; //memo[i][j]表示,[0..i]s1,[0..j]s2的最大的长度
		for(int i = 0;i<n;i++){
			if(s1.charAt(i) == s2.charAt(0)||(i>0&&memo[i][0] ==1)){
				memo[i][0] = 1;
			}
		}
		for(int j = 0;j<m;j++){
			if(s2.charAt(0) == s1.charAt(0) || (j>0&&memo[0][j] == 1)){
				memo[0][j] = 1;
			}
		}
		for(int i = 1;i<n;i++){
			for(int j = 1;j<m;j++){
				int maxlength = 0;
				if(s1.charAt(i) == s2.charAt(j)){
					maxlength = memo[i-1][j-1] + 1;
				}else{
//					maxlength = Math.max(maxlength,memo[i-1][j]);  //这里如果不相等的话,只能是小
					maxlength = Math.max(memo[i-1][j],memo[i][j-1]);
				}
				memo[i][j] = maxlength;
			}
		}
		return memo[n-1][m-1];
	}
	//这里要打印最大的长度字符串
	public String printLCS(String s1,String s2){
		int n = s1.length()-1;
		int m = s2.length()-1;
		int maxlength = getMaxLength(s1,s2);  //得到最大的
		StringBuilder ss = new StringBuilder();
		while(n>=0&&m>=0){
			if(s1.charAt(n) == s2.charAt(m)){
//				ss.append(s1.charAt(n));
				ss.insert(0,s1.charAt(n));
				n--;
				m--;
			}else if(n==0){
				m--;
			}else if(m==0){
				n--;
			}else{
				if(memo[n-1][m]>memo[n][m-1]){
					n--;
				}else{
					m--;
				}
			}
		}
		return ss.toString();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值