
题目描述
给定字符串 s
,找出最长重复子串的长度。如果不存在重复子串就返回 0
。
示例 1:
输入:"abcd"
输出:0
解释:没有重复子串。
示例 2:
输入:"abbaba"
输出:2
解释:最长的重复子串为 "ab" 和 "ba",每个出现 2 次。
示例 3:
输入:"aabcaabdaab"
输出:3
解释:最长的重复子串为 "aab",出现 3 次。
提示:
1 <= s.length <= 2000
- 字符串
s
仅包含从 'a'
到 'z'
的小写英文字母。
解法
方法一:动态规划
我们定义 \(f[i][j]\) 表示以 \(s[i]\) 和 \(s[j]\) 结尾的最长重复子串的长度,初始时 \(f[i][j]=0\)。
我们在 \([1, n)\) 的区间内枚举 \(i\),在 \([0, i)\) 的区间内枚举 \(j\),如果 \(s[i]=s[j]\),那么有:
\[
f[i][j]=
\begin{cases}
f[i-1][j-1]+1, & j>0 \\
1, & j=0
\end{cases}
\]
我们求出所有 \(f[i][j]\) 的最大值即为答案。
时间复杂度 \(O(n^2)\),空间复杂度 \(O(n^2)\)。其中 \(n\) 为字符串 \(s\) 的长度。
相似题目:
| class Solution:
def longestRepeatingSubstring(self, s: str) -> int:
n = len(s)
f = [[0] * n for _ in range(n)]
ans = 0
for i in range(1, n):
for j in range(i):
if s[i] == s[j]:
f[i][j] = 1 + (f[i - 1][j - 1] if j else 0)
ans = max(ans, f[i][j])
return ans
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | class Solution {
public int longestRepeatingSubstring(String s) {
int n = s.length();
int[][] f = new int[n][n];
int ans = 0;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (s.charAt(i) == s.charAt(j)) {
f[i][j] = 1 + (j > 0 ? f[i - 1][j - 1] : 0);
ans = Math.max(ans, f[i][j]);
}
}
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | class Solution {
public:
int longestRepeatingSubstring(string s) {
int n = s.length();
int f[n][n];
memset(f, 0, sizeof(f));
int ans = 0;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (s[i] == s[j]) {
f[i][j] = 1 + (j > 0 ? f[i - 1][j - 1] : 0);
ans = max(ans, f[i][j]);
}
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | func longestRepeatingSubstring(s string) (ans int) {
n := len(s)
f := make([][]int, n)
for i := range f {
f[i] = make([]int, n)
}
for i := 1; i < n; i++ {
for j := 0; j < i; j++ {
if s[i] == s[j] {
if j > 0 {
f[i][j] = f[i-1][j-1]
}
f[i][j]++
ans = max(ans, f[i][j])
}
}
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | function longestRepeatingSubstring(s: string): number {
const n = s.length;
const f: number[][] = Array.from({ length: n }).map(() => Array(n).fill(0));
let ans = 0;
for (let i = 1; i < n; ++i) {
for (let j = 0; j < i; ++j) {
if (s[i] === s[j]) {
f[i][j] = 1 + (f[i - 1][j - 1] || 0);
ans = Math.max(ans, f[i][j]);
}
}
}
return ans;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | impl Solution {
pub fn longest_repeating_substring(s: String) -> i32 {
let n = s.len();
let mut f = vec![vec![0; n]; n];
let mut ans = 0;
let s = s.as_bytes();
for i in 1..n {
for j in 0..i {
if s[i] == s[j] {
f[i][j] = if j > 0 { f[i - 1][j - 1] + 1 } else { 1 };
ans = ans.max(f[i][j]);
}
}
}
ans
}
}
|