最长公共子序列
题目:
链接: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 }