找到最长的重复子数组

Find the longest repeated subarray

给定一个 a[0..N-1] 整数数组 0 < N < 10^5,找到 最长重复子数组 在最佳时间和 space 之间的大小.我正在考虑使用 HashMap 来存储数字开始的索引,并开始检查每个索引可能形成的子数组。但这似乎效率低下,所以我想听听一些关于如何解决这个问题的意见。

示例:

输入a = [0,1,2,1,4,1,2,1,0,5]
预期输出:Most Repeated: [1,2,1]; Size: 3

我相信,这道题等同于寻找最长的重复子串,https://en.wikipedia.org/wiki/Longest_repeated_substring_problem. If overlapping substrings are allowed, the problem can be efficiently solved using a suffix tree in linear time. However, in this case it seems that identifying non-overlapping substrings is required, and this approach doesn't work. At least, it can be solved in quadratic time using dynamic programming, https://www.geeksforgeeks.org/longest-repeating-and-non-overlapping-substring/

众所周知,此类问题采用的是一种天真的方法 - 需要花费大量时间并针对所有可能的解决方案执行强力搜索。

显然,您不是在寻找那个。每当您遇到这种情况时,答案总是动态规划。它相当广泛,对初学者来说很难,但在计算机科学中非常重要。这意味着,我不能在这个答案中涵盖它。

但是这里有一个方法可以解决这个问题。

由于 A 和 B 的公共子数组必须从某些 A[i]B[j] 开始,让 dp[i][j] 成为 A[i:] 和 [=14 的最长公共前缀=].每当A[i] == B[j],我们就知道dp[i][j] = dp[i+1][j+1] + 1。此外,答案是 max(dp[i][j])ij

我们可以根据这个递推进行自下而上的动态规划来寻找答案。我们的循环不变量是答案已经正确计算并存储在 dp 中,用于任何更大的 ij.

希望这对您有所帮助。祝你好运。