(24)718. 最长重复子数组

本文探讨了LeetCode上编号718的题目——最长重复子数组,通过两种方法进行解答:动态规划和滑动窗口。动态规划方法利用二维数组记录两数组间的最长公共前缀,而滑动窗口方法则通过固定一个数组并让另一个数组滑动来寻找最长公共子数组。

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

题目链接:
https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/
困难度:中等
718. 最长重复子数组
	给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例 1:
	输入:
		A: [1,2,3,2,1]
		B: [3,2,1,4,7]
	输出: 3
解释: 
	长度最长的公共子数组是 [3, 2, 1]。
说明:
	1 <= len(A), len(B) <= 1000
	0 <= A[i], B[i] < 100

不会。。。 根据官方的思路 写了一下
动态规划 没想到 比较容易理解
dp[i][j] 是 A[i: ],B[j: ]的最长公共前缀
dp[i-1][j-1] = dp[i][j]+! 或者 0 ( A[i] == B[j] )
不过执行时间和内存消耗都挺高的

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size(), m = B.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
        int ans = 0;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                dp[i][j]=A[i]==B[j]?dp[i+1][j+1]+1:0;
                ans=max(ans,dp[i][j]);        
            }
        }
        return ans;
    }
};

还有个思路是滑动窗口 之前做题用过 这个没想到 好垃圾
以A B分别为基准 如 使A不动 B滑动 B[i]为开始(i范围为 0-(n-1)) 得到 A 与B[i:] 之间的公共前缀

class Solution {
public:
	//  a--A   b--B  a,b有一个为0   若a为0 则此时A不动
    int maxLength(vector<int>& A, vector<int>& B, int a, int b, int len) {
        int ret = 0, k = 0;
        for (int i = 0; i < len; i++) {
            if (A[a + i] == B[b + i]) {
                k++;
            } else {
                k = 0;
            }
            ret = max(ret, k);
        }
        return ret;
    }
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size(), m = B.size();
        int ret = 0;
        // 
        for (int i = 0; i < n; i++) {
            int len = min(m, n - i);
            int maxlen = maxLength(A, B, i, 0, len);
            ret = max(ret, maxlen);
        }
        for (int i = 0; i < m; i++) {
            int len = min(n, m - i);
            int maxlen = maxLength(A, B, 0, i, len);
            ret = max(ret, maxlen);
        }
        return ret;
    }

};

官网还有一种方法 没看懂 有时间在说。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值