给两个整数数组 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[i][j] ,[i]是A的前i个数据构成的子数组,[j]是B的前j个数据构成的子数组,那么dp[i][j]表示这两个子数组的最长公共后缀的长度。本题所求解的问题必然是max(dp[i][j])。
- 当A[i]==B[j]时,dp[i][j]=dp[i-1][j-1]+1。如果i==0||j==0,dp[i][j]=1;
- 当A[i]!=B[j]时,dp[i][j]=0;
原则上需要一个二维数组,但是仔细观察会发现,每一次只用了前一列的上一行元素,于是可以将二维数组转换成一维数组,从小到大遍历每一列,每一列的遍历是,行数从大到小,更新数据即可。
- 当A[i]==B[i]时,dp[i]=dp[i-1]+1。如果i=0||j==0,dp[i]=1.
- 当A[i]!=B[j]时,dp[i]=0;
dp | 3 | 2 | 1 | 4 | 7 |
1 | 0 | 0 | 1 | 0 | 0 |
2 | 0 | 1 | 0 | 0 | 0 |
3 | 1 | 0 | 0 | 0 | 0 |
2 | 0 | 2 | 0 | 0 | 0 |
1 | 0 | 0 | 3 | 0 | 0 |
class Solution { public: int findLength(vector<int>& A, vector<int>& B) { int sizeA = A.size(), sizeB = B.size(), i, j; int max = 0; int dp[1000] = { 0 }; for (j = 1; j <= sizeB; j++) { for (i = sizeA; i >= 1; i--) { if (A[i - 1] != B[j - 1]) dp[i - 1] = 0; else { dp[i - 1] = j > 1 && i > 1 ? dp[i - 2] + 1 : 1; if(max<dp[i-1]) max = dp[i-1]; } } } return max; } }; |