我的理解:用两个for循环依次比较nums1和nums2里面的数,如果nums1中的某个数和nums2中的某个数相同,则dp[i][j]=1;
如果:nums1 = [3,2,1,4,7];nums2 = [1,2,3,2,1];打印dp数组看看。
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = 1;
}
}
}
// 打印dp
[
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 1, 0, 1, 0 ],
[ 0, 1, 0, 0, 0, 1 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ]
]
题目要求获取两个数组的公共子序列的长度,公共连续的子数组只可能存在于从某一个左上角到右下角连起来的“对角线”。所以我们想要的dp表格应该长这样 :
[
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 1, 0, 2, 0 ],
[ 0, 1, 0, 0, 0, 3 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ]
]
如何打印出想要的dp数组呢,因为dp[i][j]
只依赖上一行上一列的对角线的值。我们只需要这样做:
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
循环期间,用一个变量不断刷新dp表格中出现的最大值,循环结束,返回即可。
完整代码:
var findLength = function (nums1, nums2) {
const m = nums1.length;
const n = nums2.length;
const dp = new Array(m + 1).fill(0).map(v => new Array(n + 1).fill(0));
let res = 0;
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
// 只有遇到nums1[i - 1] == nums2[j - 1],才更新dp
if (nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
res = Math.max(dp[i][j], res);
}
}
return res;
};