Maximum Length of Repeated Subarray 最长重复子数组

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

示例 1:

输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出: 3
解释: 
长度最长的公共子数组是 [3, 2, 1]。

说明:

  1. 1 <= len(A), len(B) <= 1000
  2. 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;     
    }



猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/80723455
今日推荐