LeetCode 718. 最长重复子数组

这篇博客探讨了如何使用动态规划优化解决寻找两个数组最长公共子序列的问题。初始的暴力方法由于时间复杂度过高导致超时,作者随后介绍了二维数组的方法,通过维护左斜上角元素的值来降低时间复杂度,最终实现AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一开始想到的就是暴力的写法,通过多次循环遍历找到最长的子序列,但是最坏的情况下时间复杂度会达到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=1j=1时,此时我们获得了第一个子序列,其长度为1,当第二次出现相等时,即i=2j=2时,此时我们获得了第二个子序列,长度还是为1,但是我们发现此时的数组坐标为(i-1, j-1)处不为0,而且i-1j-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;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值