最长重复子串

给定字符串 S,找出最长重复子串的长度。如果不存在重复子串就返回 0。

示例 1:

输入:“abcd”
输出:0
解释:没有重复子串。
示例 2:

输入:“abbaba”
输出:2
解释:最长的重复子串为 “ab” 和 “ba”,每个出现 2 次。
示例 3:

输入:“aabcaabdaab”
输出:3
解释:最长的重复子串为 “aab”,出现 3 次。
示例 4:

输入:“aaaaa”
输出:4
解释:最长的重复子串为 “aaaa”,出现 2 次。

提示:

字符串 S 仅包含从 ‘a’ 到 ‘z’ 的小写英文字母。
1 <= S.length <= 1500

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-repeating-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:暴力法,遍历
对于每一个下标我们枚举从该下标开始,可能的所有子串

    /* 使用暴力的办法进行求解,寻找所有的字符串 */
    public static int longestRepeatingSubstring1(String S) {
        int maxLen = 0;
        for (int i = 0; i < S.length(); i++) {
            for (int j = i + 1; j < S.length(); j++) {
                int len = comlen(S, i, j);
                if (len > maxLen) {
                    maxLen = len;
                }
            }
        }
        return maxLen;
    }

    // 计算公共子串的长度
    private static int comlen(String S, int i, int j) {
        int len = 0;
        while (i < S.length() && j < S.length()
                && S.charAt(i++) == S.charAt(j++)) {
            len++;
        }
        return len;
    }

解法二:使用后缀数组

求出一个数组的所有后缀子串,然后对后缀子串进行排序,(如果该字符串中含有重复子串,那么排序后两个含有相同子串的后缀会相邻,然后重复子串的长度)
例子:
abbaba
该字符串的所有后缀:
[abbaba, bbaba, baba, aba, ba, a]
我们对所有的后缀进行排序:
[a, aba, abbaba, ba, baba, bbaba]
排序后含有相同子串的后缀会相邻,我们通过计算相邻两个后缀的最长的公共子串长度来得到最长的重复子串。


    // 后缀数组求最长重复子串
    public static int longestRepeatingSubstring2(String str) {
        StringBuilder sourceStr = new StringBuilder(str);
        String[] strings = new String[str.length()];
        strings[0] = str;
        // 求这个字符串的所有的后缀
        for (int i = 1; i < str.length(); i++) {
            // 每次删除最开始的字符
            strings[i] = sourceStr.delete(0, 1).toString();
        }
        System.out.println(Arrays.toString(strings));
        Arrays.sort(strings);
        System.out.println(Arrays.toString(strings));
        int maxLen = 0;
        for (int i = 0; i < str.length() - 1; i++) {
            int len = comlen2(strings[i], strings[i + 1]);
            if (len > maxLen) {
                maxLen = len;
            }
        }
        return maxLen;
    }

    private static int comlen2(String string1, String string2) {
        int len = 0;
        int index1 = 0;
        int index2 = 0;
        while (index1 < string1.length() && index2 < string2.length() && string1.charAt(index1) == string2.charAt(index2)) {
            index1++;
            index2++;
            len++;
        }
        return len;
    }

你可能感兴趣的:(algorithm)