题目
给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例:
输入: 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数组和下标
dp[i][j]
代表以A[i-1]
与B[j-1]
结尾的公共字串的长度 - 确定递推公式
dp[i][j]
的状态只能由dp[i - 1][j - 1]
推导出来,即当A[i - 1]
和B[j - 1]
相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1
,其中i,j
从1开始遍历 - dp数组初始化
dp[i][0]
和dp[0][j]
其实都是没有意义的,但是为了方便递推公式dp[i][j] = dp[i - 1][j - 1] + 1
,所以是需要初始值的
dp[i][0]= dp[0][j] = 0
- 确定遍历顺序
A、B两个for循环没有内外层区分,都可以,因为要求长度最长的子数组的长度,所以在遍历的时候把dp[i][j]
的最大值记录下来 - 举例推导dp数组
拿示例1中,A: [1,2,3,2,1],B: [3,2,1,4,7]为例,画一个dp数组的状态变化,如下:
java代码如下:
class Solution {
public int findLength(int[] nums1, int[] nums2){
int result = 0;
int[][] dp = new int[nums1.length + 1][nums2.length + 1];//因为i是从1开始遍历,0没有意义,所以开创长度要加一
for(int i = 1 ; i < nums1.length + 1; i++){
for(int j = 1; j < nums2.length + 1; j++){
if(nums1[i-1] == nums2[j-1]){//即A[i-1]和B[j-1]相等时
dp[i][j] = dp[i-1][j-1] + 1;
result = Math.max(dp[i][j],result);
}
}
}
return result;
}
}