求一个字符串中最长的重复串

177 阅读1分钟

    这个问题有很多种不同时间复杂度的解法。本文讲述的是一种O(n^2)的解法。前面一篇文章我们讲到了KMP算法(搜索我的专栏标题为"KMP算法"),利用了next数组查找匹配子串。同样,我们利用next数组求一个字符串中最长的重复串。
    由next数组的理解可知,其next[j]的值表示的含义是模式串位置j往前的子串中,出现两个最大重复串的第一个重复串的最后一个字符的位置+1(实在不知道怎么用语言描述了..我举个例子解释)。如下图,假如模式串位置j往前的子串是"abcdfabc",显而易见,最大重复串为"abc",因此next[j]的值表示的含义是第一个重复串"abc"的最后一个字符'c'的位置+1,就是'd'的位置。所以,本算法的思路就是对字符串S的每一个子串求它的next数组,最后,比较所有的next数组,其中元素值最大的,他所对应的子串就是这个字符串中最长的重复串。代码如下所示:

public static String getMaxRepeatStr(String str){
        int max = -1;
        String rst = "";
        String subStr = str;
        while (subStr.length()!=0){
            int[] next = new int[subStr.length()];
            getNext(subStr,next);
            int maxForNext = -1;
            int original = 0;
            for(int i=0;i<next.length;i++){
                if(next[i] > maxForNext) {
                    maxForNext = next[i];
                    original = i;
                }
            }
            if(maxForNext > max){
                max = maxForNext;
                if(subStr.charAt(original) == subStr.charAt(maxForNext)) rst = subStr.substring(0,maxForNext+1);
                else rst = subStr.substring(0,maxForNext);
            }
            if(subStr.length()>1) subStr = subStr.substring(1);
            else subStr = "";
        }
        return rst;
    }
    

此算法的时间复杂度为O(Length(S)*Length(S))。