718. 最长重复子数组

本文讨论了如何使用暴力法寻找两个数组的最长重复子数组,以及如何通过滑动窗口算法优化时间复杂度。暴力法的时间复杂度为O(n*m*min(m,n)),而滑动窗口法改进为O(n+m)*min(m,n),同时保持空间复杂度为O(1)。
摘要由CSDN通过智能技术生成

Problem: 718. 最长重复子数组

文章目录

暴力

时间复杂度 O ( n ∗ m ∗ m i n ( m , n ) ) O(n*m*min(m, n)) O(nmmin(m,n)) n,m分别代表两个数组的长度
空间复杂度 O ( 1 ) O(1) O(1)

class Solution:
    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        # 暴力 先找到两个数组相等的位置 然后依次往后判断是否都相等
        size1 = len(nums1)
        size2 = len(nums2)

        ans = 0
        for i in range(size1):
            for j in range(size2):
                # 找到相等的位置
                if nums1[i] == nums2[j]:
                    seq_len = 1 # 公共子数组的长度
                    while i + seq_len < size1 and j + seq_len < size2 and nums1[i+seq_len] == nums2[j+seq_len]:
                        seq_len += 1
                    ans = max(ans, seq_len)
        return ans

滑动窗口

暴力的问题是找到两个数组相等的位置需要花费大量的时间,这里面有重叠
滑动窗口:
将两个数组视为两把尺子,固定nums1,nums2的尾部与nums1的头部对齐,移动nums2直到nums2的头部与nums1的尾部对齐,每次滑动只需要计算两个数组重叠部分的子数组的最大公共数组长度即可。

image.png

时间复杂度 O ( n + m ) ∗ m i n ( m , n ) ) O(n+m)*min(m, n)) O(n+m)min(m,n)) n,m分别代表两个数组的长度
空间复杂度 O ( 1 ) O(1) O(1)

class Solution:
    def findLength(self, nums1: List[int], nums2: List[int]) -> int:
        # 滑动窗口,将两个数组视为尺子 固定nums1 不断移动nums2
        n1 = len(nums1)
        n2 = len(nums2)
        def findMaxLength(nums1, nums2, i, j):
            cur_len = 0
            max_len = 0

            while i < n1 and j < n2:
                if nums1[i] == nums2[j]:
                    cur_len += 1
                    max_len = max(max_len, cur_len)
                else:
                    cur_len = 0
                
                i += 1
                j += 1
            return max_len

        res = 0
        # 固定nums1,nums2向左滑动,对应的过程是nums2的头部从左滑动到nums1头部的逆过程
        for i in range(n2):
            res = max(res, findMaxLength(nums1, nums2, 0, i))

            # res = max(res, findMaxLength(nums1, nums2, 0, n2-1-i))
            # 也可以写成这样

        # 固定nums2,nums1向左滑动,等价于nums2向右滑动,对应的过程是nums2的头部从左滑动到nums1的尾部
        for i in range(n1):
            res = max(res, findMaxLength(nums1, nums2, i, 0))
    
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aJupyter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值