LeetCode: 718.最长重复子数组

题目

给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。

解法

滑窗法

首先想到的就是滑动法,就像卷积一样,其中一个序列从另一个数组的左边一直滑到右边,然后交叠部分挨个比较。
分三部分:1. 序列A逐渐全部走进序列B。2. 序列A完全在B中滑动。3.序列A逐渐离开B

class Solution:
    def findLength(self, A: List[int], B: List[int]) -> int:
        m = len(A)
        n = len(B)
        if m>n:
            m, n, A, B = n, m, B, A
        # A smaller, 默认是B在滑动,即长的序列参照A滑动
        cnt = 0
        for i in range(1, m+1): # 第一部分
            cnt = max(cnt, self.count(A, 0, B, n-i, i))
        for i in range(n-m-1, -1, -1): # 第二部分
            cnt = max(cnt, self.count(A,0, B, i, m))
        for i in range(1, m):  # 第三部分
            cnt = max(cnt, self.count(A, i, B, 0, m-i))
        return cnt

    def count(self, a, i, b, j, leng):
        cnt = 0
        max_cnt = 0
        for k in range(leng):
            if a[i+k] == b[j+k]:
                cnt += 1
                max_cnt = max(max_cnt, cnt)
            else:
                cnt = 0
        return max_cnt

动态规划

dp[i][j] 代表以A[i] 和B[i]为起点的A[i:], B[i:],他们的最长公共子数组的数目。所以递归方程为
当A[i] == B[i],说明可以在dp[i+1][j+1]的基础上加1,代表以A[i]为起点的公共子树组的长度。如果不相等,则为0.
最后返回的就是dp的每一行的最大值的最大值。

class Solution:
    def findLength(self, A: List[int], B: List[int]) -> int:
        m = len(A)
        n = len(B)
        dp = [[0]*(n+1) for _ in range(1+m)]
        for i in range(m-1, -1, -1):
            for j in range(n-1, -1, -1):
                if A[i] == B[j]:
                    dp[i][j] = dp[i+1][j+1] + 1
        return max(max(row) for row in dp)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值