题目
给两个整数数组 nums1
和 nums2
,返回 两个数组中 公共的 、长度最长的子数组的长度 。
示例 1:
输入:nums1 = [1,2,3,2,1], nums2 = [3,2,1,4,7]
输出:3
解释:长度最长的公共子数组是 [3,2,1] 。
示例 2:
输入:nums1 = [0,0,0,0,0], nums2 = [0,0,0,0,0]
输出:5
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 100
解题方法
动态规划
设定动态数组
dp[i][j]
表示数组1
截止到下标i-1
处和数组2
下标截止到j-1
处对应的公共最长子数组的长度,记录dp
数组最大值,递推公式如下:
为了进一步压缩空间复杂度,将该二维数组压缩为一维数组dp[j]
。
时间复杂度O(n1*n2)
,空间复杂度O(n2)
。
C++代码:class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size();
int n2 = nums2.size();
vector<int> dp(n2+1, 0);
int result = 0;
for(int i=0; i<n1; i++) {
for(int j=n2; j>0; j--) {
dp[j] = nums1[i] == nums2[j-1] ? dp[j-1]+1 : 0;
result = result > dp[j] ? result : dp[j];
}
}
return result;
}
};
滑动窗口
寻找最长重复子数组可以看做一个数组固定,另一个数组滑动,随后在重叠区域内求最长的重复子数组长度即可。
时间复杂度O((m+n)*min(m+n))
,空间复杂度O(1)
。
C++代码:class Solution { public: int getmaxsub(vector<int>& nums1, vector<int>& nums2) { int n1 = nums1.size(); int n2 = nums2.size(); int result = 0; for(int i=0; i<n1; i++) { int len = min(n1-i, n2); int tmp = 0; for(int k=0; k<len; k++) { tmp = nums1[i+k]==nums2[k] ? ++tmp : 0; result = result > tmp ? result : tmp; } } return result; } int findLength(vector<int>& nums1, vector<int>& nums2) { int result1 = getmaxsub(nums1, nums2); int result2 = getmaxsub(nums2, nums1); return result1 > result2 ? result1 : result2; } };