动态规划 -- 最长公共子序列(LCS)-- java

最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不一样。
子序列:公共序列 可以不相邻
公共子串:公共序列的字符必须连续。
公共子数组: 数组索引必须连续

在这里插入图片描述
在这里插入图片描述

方法一:

  • 暴力法解题
    * 即求出所有的子序列,找出最长的。
    * 显然这是一个愚蠢的解法,竞赛必超时,面试必凉。
    * 这里就不详述了。

方法二:

  • 动态规划法
  • 例如:求字符串Str1 = a b m n c , Str2 = a p b c q.

对于两个字符串的动态规划问题,套路是通用的,所以可以以模板的方法记下本类题目
构建DP table:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
至此,我们可以求得最长公共子序列的长度,但是我们还要输出序列
在这里插入图片描述完整代码:

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
	  Scanner in = new Scanner(System.in);
	  String str1 = in.nextLine();
	  String str2 = in.nextLine();
	  dp(str1, str2);
    }
    public static void dp(String str1,String str2) {
	  int len1 = str1.length();
	  int len2 = str2.length();
	  int[][] dpTable = new int[len1+1][len2+1];
	  //初始化第一列
	  int flag = 0;
	  for(int i=1;i<=len1;i++) {
	      if(flag == 1) {
	   	  dpTable[i][1] = 1;
	      }else if(str1.charAt(i-1)==str2.charAt(0) ) {
	          dpTable[i][1]=1;
	          flag = 1;
	      }else {
	          dpTable[i][1] = 0;
	      }
	  }
	  // 初始化第一行
	  flag = 0;
	  for(int j =1;j<=len2;j++) {
	      if(flag == 1) {
	          dpTable[1][j] = 1;
	      }else if(str2.charAt(j-1)==str1.charAt(0) ) {
	          dpTable[1][j]=1;
	      str.append(str2.charAt(j-1));
	      flag = 1;
	      }else {
	          dpTable[1][j] = 0;
	      }
	  }
	  for(int i=2;i<len1;i++) {
	       for(int j= 2;j<len2;j++) {
   		    if(str1.charAt(i)==str2.charAt(j)&& !already) {
    			 dpTable[i+1][j+1] = 1+ Math.max(dpTable[i][j],
    				Math.max(dpTable[i][j+1], dpTable[i+1][j]));
    		    }else {
     			 dpTable[i+1][j+1] = Math.max(dpTable[i][j+1], dpTable[i+1][j]);
   		    }
 	        }
          }
          System.out.println(dpTable[len1][len2]);
     }
}

在这里插入图片描述

输出最长子序列,请看下文
有DP-table逆向推出序列

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值