一:题目
二:上码
class Solution {
public:
/**
思路:
1.分析题意:
1 2 3 6 7 4
1 2 6 7 4 3
这里我们先遇到的1 2 但后来我们又遇见了6 7 4 那么我们的要的答案就是动态变化的
2.动态规划五步走
1>:确定dp数组以及下标的含义
dp[i][j] 表示 以下标i-1结尾的A数组和以下标j-1结束的B数组的 最长重复子数组长度
这里我们用i-1和j-1 主要是考虑当我们比较最后一个元素的时候
即: dp[i][j] = dp[i-1][j-1] + 1;//如果最后一个元素相等的话 那么
//dp[i-1][j-1]表示的是我们累加的最后一个元素
2>:确定dp数组的状态递推公式
在这个组成的二维矩阵中 我们是需要 左上角的值进行累加 因为我们是要求的是连续的长度
所以 dp[i][j] = dp[i-1][j-1] + 1;//dp[i-1][j-1] 就是左上角的值
3>:确定dp数组的初始化
初始化为0即可
4>确定dp数组的遍历顺序
外层A数组 内层B数组
5>:举例验证
dp数组下标范围 0 1 2 3 4 5
数组下标范围 0 1 2 3 4
1 2 3 2 1
0 0 0 0 0 0
3 0 0 0 1 0 0
2 0 0 1 0 2 0
1 0 1 0 0 0 3
4 0 0 0 0 0 0
7 0 0 0 0 0 0
我们之所以将dp数组的范围扩大一位 是因为我们求取第一个值相等的时候 需要用到dp[i-1][j-1]也就是
左上角的值,所以我们扩大一位
那么与之一块改变的还需注意的是 我们dp数组下标的含义 我们都是从i-1和j-1来说的 只有这样我们才能
和num1,num2数组下标对应上
例如本题的结果 dp[3][5] 表示的就是以下标2结尾的num2数组和以下标4结尾的num1数组 最长的重复子数组
*/
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int> >dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
int ans = 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(dp[i][j] > ans) ans = dp[i][j];
}
}
return ans;
}
};