题目:
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
class Solution {
/*
dp[i][j] 以 i-1 结尾的A数组和以 j-1 结尾的B数组公共最长的子数组(也就是连续子序列)是dp[i][j]
为什么表示 i-1 和 j-1 对应的状态呢?你想想如果不这样,
你还需要找前一个的状态,在初始化的时候就没那么顺理成章了
所以纯属是为了方便写代码啦
*/
public:
// int findLength(vector<int>& nums1, vector<int>& nums2)
// {
// // dp 数组需要初始化为 size+1 , 想想也是可以想通的,你看dp[i][j] 其实是表示的 i-1 和 j-1
// // 因此不多一个的话,就会把 nums 的最后一个元素漏掉,可想明白了昂
// vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0));
// int result = 0;
// for(int i = 1; i <= nums1.size(); ++i)
// {
// for(int j = 1; j <= nums2.size(); ++j)
// {
// if(nums1[i - 1] == nums2[j - 1])
// {
// dp[i][j] = dp[i - 1][j - 1] + 1;
// }
// if(result < dp[i][j])
// {
// result = dp[i][j];
// }
// }
// }
// return result;
// }
// 使用滚动数组,
// 注意此时只需要将 dp 定义为 内层数组的大小+1 即可,而且遍历的时候,需要从后向前,这样避免重复覆盖
int findLength(vector<int>& nums1, vector<int>& nums2)
{
vector<int> dp(nums2.size() + 1, 0);
int result = 0;
for(int i = 1; i <= nums1.size(); ++i)
{
for(int j = nums2.size(); j > 0; --j)
{
if(nums1[i - 1] == nums2[j - 1])
{
dp[j] = dp[j - 1] + 1;
}
else
{
// 求连续子序列的时候都会有这个套路,注意了昂~
dp[j] = 0;
}
if(result < dp[j])
{
result = dp[j];
}
}
}
return result;
}
};