718. 最长重复子数组
给两个整数数组 A
和 B
,返回两个数组中公共的、长度最长的子数组的长度。
示例:
输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出:3
解释:
长度最长的公共子数组是 [3, 2, 1] 。
分析:
分析一个问题的最优解,通常是从暴力解法的优化延伸而来。就如示例,如果要找到[3, 2, 1],必须要进行大量的重复比较。避免重复比较,就会想到动态规划。同时由于数组的特性,可以利用滑动窗口。
方法一:
动态规划
方法二:
滑动窗口
代码(Golang):
方法一:
func findLength(A []int, B []int) int {
n, m := len(A), len(B)
dp := make([][]int, n + 1)
for i := 0; i < len(dp); i++ {
dp[i] = make([]int, m + 1)
}
ans := 0
for i := n - 1; i >= 0; i-- {
for j := m - 1; j >= 0; j-- {
if A[i] == B[j] {
dp[i][j] = dp[i + 1][j + 1] + 1
} else {
dp[i][j] = 0
}
if ans < dp[i][j] {
ans = dp[i][j]
}
}
}
return ans
}
方法二:
func findLength(A []int, B []int) int {
n, m := len(A), len(B)
ret := 0
for i := 0; i < n; i++ {
len := min(m, n - i)
maxLen := maxLength(A, B, i, 0, len)
ret = max(ret, maxLen)
}
for i := 0; i < m; i++ {
len := min(n, m - i)
maxLen := maxLength(A, B, 0, i, len)
ret = max(ret, maxLen)
}
return ret
}
func maxLength(A, B []int, addA, addB, len int) int {
ret, k := 0, 0
for i := 0; i < len; i++ {
if A[addA + i] == B[addB + i] {
k++
} else {
k = 0
}
ret = max(ret, k)
}
return ret
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func min(x, y int) int {
if x < y {
return x
}
return y
}