Maximum Length of Repeated Subarray 最長重複子陣列
阿新 • • 發佈:2019-02-04
給兩個整數陣列 A
和 B
,返回兩個陣列中公共的、長度最長的子陣列的長度。
示例 1:
輸入: A: [1,2,3,2,1] B: [3,2,1,4,7] 輸出: 3 解釋: 長度最長的公共子陣列是 [3, 2, 1]。
說明:
- 1 <= len(A), len(B) <= 1000
- 0 <= A[i], B[i] < 100
思路:
採用動態規劃,通過維護一個二維陣列dp來計算最長重複子陣列。如下圖例子所示:
3 1 2
1 0 1 0
2 0 0 2
2 0 0 1
行表示A,列表示B,dp[i][j]的值為如果A[i]和B[j]相等,則dp[i][j]等於他左上角的值+1,否則等於0。
參考程式碼如下:
int findLength(vector<int>& A, vector<int>& B) { int m = A.size(); int n = B.size(); if (!m || !n) { return 0; } vector<vector<int>> dp(m+1,vector<int>(n+1,0)); int res = 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 = max(res, dp[i][j]); } } return res; }
思路2:本文可以簡化為O(n+1)的複雜度,即只需要一個一維陣列,由於我們要考慮到陣列元素覆蓋的問題,所以遞迴公式改為:
/**
* dp[i][j] = a[i] == b[j] ? dp[i + 1][j + 1] : 0;
* dp[i][j] : max lenth of common subarray start at a[i] & b[j];
*/
且遍歷A和B的方式發生了改變,如下圖所示(綠線所示):
參考程式碼如下:
int findLength(vector<int>& A, vector<int>& B) { int m = A.size(); int n = B.size(); if (!m || !n) { return 0; } vector<int> dp(n+1,0); int res = 0; for (int i = m-1; i >=0; i--) { for (int j = 0; j < n; j++) { dp[j] = (A[i] == B[j]) ? dp[j + 1] + 1 : 0; res = max(res, dp[j]); } } return res; }