最长公共子序列

题目:

链接:https://www.nowcoder.com/questionTerminal/9ae56e5bdf4f480387df781671db5172
来源:牛客网

我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度。

输入描述:

输入包含多组数据。

每组数据包含两个字符串m和n,它们仅包含字母,并且长度不超过1024。


输出描述:

对应每组输入,输出最长公共子序列的长度。
示例1
输入

abcfbc abfcab
programming contest
abcd mnp
输出

4
2
0

 

解法:动态规划。

简历一个dp矩阵,dp[i][j]代表str1[0...i-1]和str2[0...j-1]的最长公共子序列的长度。则dp[i-1][j-1]为:

若str1[i-1] != str2[j-1],则dp[i][j] = max(dp[i-1][j], dp[i][j-1]);

若str1[i-1] == str2[j-1],则dp[i][j] = max(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]+1);

最后返回dp[mLength][nLength]

 1 import java.util.Scanner;
 2 
 3 public class Main{
 4     public int lcs(String m, String n) {
 5         int mLength = m.length();
 6         int nLength = n.length();
 7         int[][] dp = new int[mLength+1][nLength+1];
 8         for (int i=1; i<=mLength; i++) {
 9             for (int j=1; j<=nLength; j++) {
10                 dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
11                 if (m.charAt(i-1) == n.charAt(j-1)) {
12                     dp[i][j] = Math.max(dp[i][j], dp[i-1][j-1] + 1);
13                 }
14             }
15         }
16         return dp[mLength][nLength];
17     }
18 
19     public static void main(String[] args) {
20         Main mainObj = new Main();
21         Scanner in = new Scanner(System.in);
22         while(in.hasNext()) {
23             String m = in.next();
24             String n = in.next();
25             System.out.println(mainObj.lcs(m, n));
26         }
27         in.close();
28     }
29 }

 

posted @ 2017-11-13 08:44  HitAnyKey  阅读(201)  评论(0编辑  收藏  举报