一开始想到的就是暴力的写法,通过多次循环遍历找到最长的子序列,但是最坏的情况下时间复杂度会达到O(n3)O(n^3)O(n3)
结果就是TLE了,所以这样的方法是不可行的,还是贴一下初版的代码:
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int ans = 0;
for(int i=0;i<nums1.size();i++) {
for(int j=0;j<nums2.size();j++) {
if(nums1[i] == nums2[j]) {
int tmp = 0;
int left = i;
int right = j;
while(nums1[left] == nums2[right] && left < nums1.size() && right < nums2.size()) {
tmp++;
left++;
right++;
}
if(tmp > ans) {
ans = tmp;
}
}
}
}
return ans;
}
};
看了一份别人的题解,给了我一个新的思路,那就是通过一个二维数组进行对比。
这个二维数组的横轴和纵轴分别为数组nums1
和数组nums2
,同样是通过一个二重循环,每次循环时对比横轴和纵轴的值,如若相等,则该坐标的值为其左斜上方的坐标的值+1
。
举一个例子去理解,假如给定的两个数组分别为[1, 2, 3, 6]
和[4, 2, 3, 5]
,初始化时二维数组的所有值均为0
,当第一次出现相等时,即i=1
,j=1
时,此时我们获得了第一个子序列,其长度为1
,当第二次出现相等时,即i=2
,j=2
时,此时我们获得了第二个子序列,长度还是为1,但是我们发现此时的数组坐标为(i-1, j-1)
处不为0
,而且i-1
和j-1
的对应的分别是当前横纵坐标的前一个数,即表明当前的子序列和其前一个子序列可以合并成一个更长的子序列,这也就是为什么每一个坐标的值都为其左斜上方的值+1
的原因,思路有了,动手写代码,AC代码如下:
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int tmp[nums1.size()+1][nums2.size()+1];
memset(tmp,0,sizeof(tmp));
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]) {
tmp[i][j] = tmp[i-1][j-1] + 1;
}
if(tmp[i][j] > ans) {
ans = tmp[i][j];
}
}
}
return ans;
}
};