最长子序列子数组

1143 最长公共子序列

  • 子序列是可以不连续的
  • dp[i][j]的含义是text1[:i]和text2[:j]最长公共子序列,这个最长公共子序列不一定包含text1[i]和text2[j]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int m = text1.size(), n = text2.size();
vector<vector<int>> dp(m+1, vector<int>(n+1, 0)); // 多一行一列
for(int i=1; i<=m; ++i){
for(int j=1; j<=n; ++j){
if(text1[i-1] == text2[j-1]) dp[i][j] = dp[i-1][j-1] + 1; // 别忘了坐标偏移
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[m][n];
}
};

718 最长重复子数组

  • 子数组是连续的
  • dp[i][j]的含义是以nums1[i]结尾的nums1[:i]和以nums2[j]结尾的nums2[:j]的最长重复子数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
vector<vector<int>> dp(m+1, vector<int>(n+1, 0));
int ret = 0;
for(int i=1; i<=m; ++i){
for(int j=1; j<=n; ++j){
if(nums1[i-1] == nums2[j-1]){
dp[i][j] = dp[i-1][j-1] + 1;
ret = max(ret, dp[i][j]);
}
}
}
return ret;
}
};

错误1

如果里面写成这样:

1
2
3
4
if(nums1[i-1] == nums2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
...
return dp[m][n];

则是处理非连续的“数组子序列”,对于[0,1,1,1,1]和[1,0,1,0,1]给出的答案是3,但是正确答案应该是2

1
2
3
4
5
6
7
8
9
// 错误DP图
X | X 1 0 1 0 1
——————————————————————————
X | 0 0 0 0 0 0
0 | 0 0 1 *1 1 *1
1 | 0 1 *1 2 *2 2
1 | 0 1 *1 *2 *2 *3
1 | 0 1 *1 *2 *2 *3
1 | 0 1 *1 *2 *2 *3
1
2
3
4
5
6
7
8
9
// 正确DP图
X | X 1 0 1 0 1
——————————————————————————
X | 0 0 0 0 0 0
0 | 0 0 1 0 1 0
1 | 0 1 0 2 0 2
1 | 0 1 0 1 0 1
1 | 0 1 0 1 0 1
1 | 0 1 0 1 0 1

错误2

如果里面写成这样:

1
2
3
4
dp[i][j] == max(max(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]+1);
ret = max(ret, dp[i][j]);
...
return ret;

则属于彻底混淆了自己对于dp数组的定义,一定要是以nums1[i]结尾的子数组和以nums1[j]结尾的子数组的最长子数组,对于[1,0,0,0,1]和[1,0,0,1,1]给出的答案是4,但是正确答案应该是3

1
2
3
4
5
6
7
8
9
// 错误DP图
X | X 1 0 0 0 1
——————————————————————————
X | 0 0 0 0 0 0
1 | 0 1 0 0 0 1
0 | 0 0 2 *2 *2 0
0 | 0 0 *2 3 *3 0
1 | 0 1 0 0 0 *4
1 | 0 1 0 0 0 *4
1
2
3
4
5
6
7
8
9
// 正确DP图
X | X 1 0 0 0 1
——————————————————————————
X | 0 0 0 0 0 0
1 | 0 1 0 0 0 1
0 | 0 0 2 1 1 0
0 | 0 0 1 3 2 0
1 | 0 1 0 0 0 3
1 | 0 1 0 0 0 1