1 题目
给两个整数数组 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
2 Java
2.1 方法一(暴力;超时)
每次从A、B中取长度为l的子数组(l以短数组的长度为起始递减至1),看两个数组是否相等,如果相等,立即返回子数组长度
class Solution {
public int findLength(int[] A, int[] B) {
// 将 A 设为短数组
if(A.length < B.length){
int[] temp = A;
A = B;
B = A;
}
// PS:外面两侧 for,从数组 A 取出长度为 l 的子数组,判断数组 B 是否包含该子数组;如果是求字符串的公共子串,有API可用,数组只能自己实现了
// 判断是否有长度为 l 的公共子数组
for (int l = A.length; l > 0; l--) {
// 确定 A 的左端索引 i
for (int i = 0; i < A.length - l + 1; i++) {
// 确定 B 的左端索引 j
for (int j = 0; j < B.length - l + 1; j++) {
// 判断俩数组从各自左端起,长为 l 的子数组是否相等
int pA = i, pB = j, AEnd = i + l;
int res = 0;
while(pA < AEnd && A[pA] == B[pB]){
pA++;
pB++;
res++;
}
if(pA == AEnd){
return res;
}
}
}
}
return 0;
}
}
2.2 方法二(动归)
class Solution {
public int findLength(int[] A, int[] B) {
int res = 0;
// 创建 初始化 dp
int[][] dp = new int[A.length][B.length];
// 向前步进
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
// 当前指向的两个元素相等,才进行操作,不相等面谈
if (A[i] == B[j]) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
// 状态转移方程
dp[i][j] = dp[i - 1][j - 1] + 1;
}
// 更新公共子数组的最大长度
res = Math.max(res, dp[i][j]);
}
}
}
return res;
}
}