leetcode:718. 最长重复子数组

题目来源

题目描述

在这里插入图片描述

题目解析

这道题给了我们两个数组A和B,让返回连个数组的最长重复子数组。那么如果将数组换成字符串,实际这道题就是求 Longest Common Substring 的问题了

暴力

  • 既然是子数组,那么重复的地方一定是连续的,并且起点可以是数组中的任何地方
  • 所以可以枚举A、B子数组中任何一个相同的字符作为起点,然后向后延伸
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(),  n = nums2.size();
        int res = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if(nums1[i] == nums2[j]){ //遇到相同项
                    int subLen = 1; // 公共子序列长度至少为1
                    while (i + subLen < m && j + subLen < n && nums1[i + subLen] == B[j + subLen]){
                        subLen++;
                    }
                    res = std::max(res, subLen);
                }
            }
        }
        return res;
    }
};

时间复杂度 O(n^3)

动态规划

思考:

  • A,B数组各抽出一个前缀数组,单看它们的末尾项,如果它们俩不一样,则公共子数组肯定不包括它们两
  • 如果它们俩一样,则需要考虑它们俩前面的子数组【能为它们提供多大的公共长度】
    • 如果它们俩的前缀数组的[末尾项]不相同,由于子数组的连续性,前缀数组不能为它们俩提供公共长度
    • 如果它们俩的前缀数组的「末尾项」相同,则可以为它们俩提供公共长度
      • 至于提供多长的公共长度?这又取决于前缀数组的末尾项是否相同……

在这里插入图片描述

状态转移方程:

  • dp[i][j]:长度为i,末尾项为A[i - 1]的子数组,与长度为j,末尾项为B[j - 1]的子数组,二者的最大公共后缀子数组长度
    • 如果A[i - 1] != B[j - 1],有dp[i][j] = 0
    • 如果A[i - 1] == B[j - 1],有dp[i][j] = dp[i - 1][j - 1] + 1
  • base case:如果i0||j0,则二者没有公共部分,dp[i][j]=0
  • 最长公共子数组以哪一项为末尾项都有可能,求出每个 dp[i][j],找出最大值。

在这里插入图片描述

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值