最长公共子序列
-
给定两个字符串
text1
和text2
,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回0
。-
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
-
例如,
"ace"
是"abcde"
的子序列,但"aec"
不是"abcde"
的子序列。 -
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
-
示例 1:
输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3 。
示例 2:
输入:text1 = "abc", text2 = "abc"
输出:3
解释:最长公共子序列是 "abc" ,它的长度为 3 。
示例 3:
输入:text1 = "abc", text2 = "def"
输出:0
解释:两个字符串没有公共子序列,返回 0 。
提示:
-
1 <= text1.length, text2.length <= 1000
-
text1
和text2
仅由小写英文字符组成。 -
暴力递归,以两个字符串的最后一个位置作为观察对象
class Solution {
public:
int my_Max(int x, int y, int z) {
int res = 0;
res = x > res? x:res;
res = y > res? y:res;
res = z > res? z:res;
return res;
}
int longestCommonSubsequence(string text1, string text2) {
return getLongest(text1,text2,text1.size()-1,text2.size()-1);
}
int getLongest(string text1, string text2, int index_1, int index_2) {
if(index_1 == 0 && index_2 == 0) {
return text1[0] == text2[0] ? 1:0;
}
if(index_1 == 0 && index_2 != 0) {
if(text1[index_1] == text2[index_2]) {
return 1;
}
else {
return getLongest(text1,text2,index_1,index_2-1);
}
}
if(index_1 != 0 && index_2 == 0) {
if(text1[index_1] == text2[index_2]) {
return 1;
}
else {
return getLongest(text1,text2,index_1-1,index_2);
}
}
int p1 = getLongest(text1,text2,index_1-1,index_2);
int p2 = getLongest(text1,text2,index_1,index_2-1);
int p3;
if(text1[index_1] == text2[index_2]) {
p3 = 1+getLongest(text1,text2,index_1-1,index_2-1);
}
else p3 = 0;
return my_Max(p1,p2,p3);
}
};
- 记忆化搜索
class Solution {
public:
vector<vector<int>> dp;
int my_Max(int x, int y, int z) {
int res = 0;
res = x > res? x:res;
res = y > res? y:res;
res = z > res? z:res;
return res;
}
int longestCommonSubsequence(string text1, string text2) {
dp.resize(text1.size(),vector<int>(text2.size(),-1));
return getLongest(text1,text2,text1.size()-1,text2.size()-1);
}
int getLongest(string text1, string text2, int index_1, int index_2) {
if(dp[index_1][index_2] != -1) return dp[index_1][index_2];
if(index_1 == 0 && index_2 == 0) {
return dp[index_1][index_2] = text1[0] == text2[0] ? 1:0;
}
if(index_1 == 0 && index_2 != 0) {
if(text1[index_1] == text2[index_2]) {
return dp[index_1][index_2] = 1;
}
else {
return dp[index_1][index_2] = getLongest(text1,text2,index_1,index_2-1);
}
}
if(index_1 != 0 && index_2 == 0) {
if(text1[index_1] == text2[index_2]) {
return dp[index_1][index_2] = 1;
}
else {
return dp[index_1][index_2] = getLongest(text1,text2,index_1-1,index_2);
}
}
int p1 = getLongest(text1,text2,index_1-1,index_2);
int p2 = getLongest(text1,text2,index_1,index_2-1);
int p3;
if(text1[index_1] == text2[index_2]) {
p3 = 1+getLongest(text1,text2,index_1-1,index_2-1);
}
else p3 = 0;
return dp[index_1][index_2] = my_Max(p1,p2,p3);
}
};
- 动态规划
class Solution {
public:
vector<vector<int>> dp;
int my_Max(int x, int y, int z) {
int res = 0;
res = x > res? x:res;
res = y > res? y:res;
res = z > res? z:res;
return res;
}
int longestCommonSubsequence(string text1, string text2) {
dp.resize(text1.size(),vector<int>(text2.size(),-1));
dp[0][0] = text1[0] == text2[0] ? 1:0;
for(int i = 1; i < text2.size(); ++i) {
if(text1[0] == text2[i]) {
dp[0][i] = 1;
}
else dp[0][i] = dp[0][i-1];
}
for(int i = 1; i < text1.size(); ++i) {
if(text1[i] == text2[0]) {
dp[i][0] = 1;
}
else dp[i][0] = dp[i-1][0];
}
for(int i = 1; i < text1.size(); ++i) {
for(int j = 1; j < text2.size(); ++j) {
int p1 = dp[i-1][j];
int p2 = dp[i][j-1];
int p3;
if(text1[i] == text2[j]) {
p3 = 1+dp[i-1][j-1];
}
else p3 = 0;
dp[i][j] = my_Max(p1,p2,p3);
}
}
return dp[text1.size()-1][text2.size()-1];
}
};