跳转至

1062. 最长重复子串 🔒

题目描述

给定字符串 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\) 的长度。

相似题目:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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
    }
}

评论