最长公共子序列
给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度.
样例 1:
输入:
"ABCD" and "EDCA"
输出:
1
解释:
LCS 是 'A' 或 'D' 或 'C'
样例 2:
输入:
"ABCD" and "EACB"
输出:
2
解释:
LCS 是 "AC"
解答:
定义DP[i][j]为A的前i个字符和B的前j个字符的最大公共子序列长度
·当末尾字符相等时,DP[i][j] = DP[i-1][j-1] + 1;
·当末尾字符不相等时,DP[i][j] = max{DP[i][j-1], DP[i-1][j]};
·状态转换方程:
DP[i][j] = { DP[i-1][j-1] + 1 A[i] == A[j]
{ max{DP[i][j-1], DP[i-1][j]} A[i] != A[j]
class Solution {
public:
/**
* @param A: A string
* @param B: A string
* @return: The length of longest common subsequence of A and B
*/
int longestCommonSubsequence(string &A, string &B) {
// write your code here
// 定义DP[i][j]为A的前i个字符和B的前j个字符的最大公共子序列长度
/*
当末尾字符相等时,DP[i][j] = DP[i-1][j-1] + 1;
当末尾字符不相等时,DP[i][j] = max{DP[i][j-1], DP[i-1][j]};
状态转换方程:
DP[i][j] = { DP[i-1][j-1] + 1 A[i] == A[j]
{ max{DP[i][j-1], DP[i-1][j]} A[i] != A[j]
*/
// 0 行 0 列不用, 从1 开始
int m = A.size() + 1;
int n = B.size() + 1;
int **dp = new int*[m];
for (int i = 0; i < m; i++) {
dp[i] = new int[n];
for (int j = 0; j < n; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if(A[i-1] == B[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
}
}
int nRet = dp[m-1][n-1];
for (int i = 0; i < m; i++) {
delete[] dp[i];
}
delete[] dp;
return nRet;
}
};