给两个整数数组 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
很容易就可以想到开一个暴力解法,即枚举数组A中的起始位置i与数据B中的起始位置j,然后计算A[i:]与B[j:]的最长公共前缀k,最终答案即为所有的最长公共前缀的最大值。
时间复杂度:O(N3) 空间复杂度:O(1)
暴力解法的过程中,最坏情况下对于任意i与j,A[i]与B[j]比较了min(i+1, j+1)次,这也是导致暴力解法时间复杂度过高的根本原因。
我们可以优化这一过程,使得任意一对A[i]和B[i]都只被比较一次,这样我们自然而然想到利用这一次的比较结果,如果A[i]==B[j],那么我们知道A[i:]和B[j:]的最长公共前缀为A[i+1:]与B[j+1:]的最长公共前缀+1,否则我们知道A[i:]和B[j:]的最长公共前缀为零。
这样我们就可以提出动态规划的解法:令dp[i][j]表示A[i:]和B[j:]的最长公共前缀,那么答案即为所有dp[i][j]中的最大值,如果A[i] == B[j],那么dp[i][j] = dp[i + 1][j + 1] + 1,否则dp[i][j] = 0。
考虑到这里dp[i][j]的值从dp[i + 1][j + 1]转移得到,所以我们需要倒过来,首先计算dp[len(A) - 1][len(B) - 1],最后计算dp[0][0]。
时间复杂度: O(N×M)。
空间复杂度: O(N×M)。
N 表示数组 A 的长度,M 表示数组 B 的长度。
空间复杂度还可以再优化,利用滚动数组可以优化到 O(min(N,M))。
Alex 007 认证博客专家 机器学习 NLP TensorFlow 我是 Alex 007,一个热爱计算机编程和硬件设计的小白。为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了。如果你喜欢我的文章的话,给个三连吧!