Question
Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays.
Example 1
Input:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
Output: 3
Explanation:
The repeated subarray with maximum length is [3, 2, 1].
Note:
1 <= len(A), len(B) <= 1000 0 <= A[i], B[i] < 100
Solution one
binary search with naive check
通过定义一个函数
check(length)
c
h
e
c
k
(
l
e
n
g
t
h
)
来检查是否存在长度为
length
l
e
n
g
t
h
的common subarray。
通过binary search来寻找最长的length。
循环结束时的low要么等于mid+1>high,要么等于high,一定是最长的length+1,所以返回low-1.
循环结束时high一定等于mid,但mid可能等于length也可能等于length+1。
class Solution(object):
def findLength(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
# AC - binary search with naive check
def check(length):
subarr = {tuple(A[i:i+length]) for i in range(len(A)-length+1)}
return any(tuple(B[j:j+length]) in subarr
for j in range(len(B)-length+1))
low,high = 0,min(len(A),len(B))+1
while low<high:
mid = (low+high)//2
if check(mid):
low = mid+1
else:
high = mid
return low-1
不使用binary search寻找length即为BF方法。
***PS:
mid = (low+high)//2
#此时当low = high-1时,mid==low
mid = (low+high+1)//2
#此时当low=high-1时, mid==high
Solution dynamic programming
定义一个辅助二维列表 int[len(A)+1][len(B)+1] dp
。其中dp[i][j]为A[i], B[j]前最长common subarray 的长度。由此可知 dp[i][j] = dp[i-1][j-1] +1
。
class Solution(object):
def findLength(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
#AC--dynamic programming
dp = [[0]*(len(B)+1) for _ in range(len(A)+1)]
for i in range(1,len(A)+1):
for j in range(1,len(B)+1):
if A[i-1] == B[j-1]:
dp[i][j] = dp[i-1][j-1]+1
return max(max(row) for row in dp)
DP方法的refine,将时间复杂度提高一倍,空间复杂度由O(MN)降到O(1)。
refine DP