1. 程式人生 > >[LeetCode] Maximum Length of Repeated Subarray 最長的重複子陣列

[LeetCode] Maximum Length of Repeated Subarray 最長的重複子陣列

Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays.

Example 1:

Input:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
Output: 3
Explanation: 
The repeated subarray with maximum length is [3, 2, 1].

Note:

    1. 1 <= len(A), len(B) <= 1000
    2. 0 <= A[i], B[i] < 100

這道題給了我們兩個陣列A和B,讓我們返回連個陣列的最長重複子陣列。那麼如果我們將陣列換成字串,實際這道題就是求Longest Common Substring的問題了,而貌似LeetCode上並沒有這種明顯的要求最長相同子串的題,注意需要跟最長子序列Longest Common Subsequence區分開,關於最長子序列會在follow up中討論。好,先來看這道題,對於這種求極值的問題,DP是不二之選,我們使用一個二維的DP陣列,其中dp[i][j]表示陣列A的前i個數字和陣列B的前j個數字的最長子陣列的長度,如果dp[i][j]不為0,則A中第i個數組和B中第j個數字必須相等,比對於這兩個陣列[1,2,2]和[3,1,2],我們的dp陣列為:

  3 1 2
1 0 1 0
2 0 0 2
2 0 0 1

我們注意觀察,dp值不為0的地方,都是當A[i] == B[j]的地方,而且還要加上左上方的dp值,即dp[i-1][j-1],所以當前的dp[i][j]就等於dp[i-1][j-1] + 1,而一旦A[i] != B[j]時,直接賦值為0,不用多想,因為子陣列是要連續的,一旦不匹配了,就不能再增加長度了。我們每次算出一個dp值,都要用來更新結果res,這樣就能得到最長相同子陣列的長度了,參見程式碼如下:

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

Follow up:在開始時,博主提到了要跟最長相同子序列Longest Common Subsequence區分開來,雖然LeetCode沒有直接求最大相同子序列的題,但有幾道題利用到了求該問題的思想,比如Delete Operation for Two StringsMinimum ASCII Delete Sum for Two Strings等,詳細討論請參見評論區一樓 :)

類似題目: