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)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章