面试题[后缀数组]: 最长重复子串

题目:给定一个字符串,求出最长重复子串。

这个题目可以用后缀数组来解:对后缀数组排好序,这样重复的子串就在相邻的后缀中找就可以了。我的C++代码实现如下:

class Solution
{
public:
    string LongestRepeatingSubstring(string str)
    {
        size_t len = str.size();
        vector<string> SuffixArray(len);
        for (size_t i = 0; i < len; ++i)
            SuffixArray[i] = str.substr(i);

        sort(SuffixArray.begin(), SuffixArray.end());

        size_t maxLen = 0, idx = 0;
        for (size_t i = 0; i < len - 1; ++i)
        {
            size_t curLen = LongestPrefix(SuffixArray[i], SuffixArray[i + 1]);
            if (curLen > maxLen)
            {
                maxLen = curLen;
                idx = i;
            }
        }

        return SuffixArray[idx].substr(0, maxLen);
    }

private:
    size_t LongestPrefix(string str1, string str2)
    {
        size_t len = min(str1.size(), str2.size());
        for (size_t i = 0; i < len; ++i)
            if (str1[i] != str2[i])
                return i;
        return len;
    }
};
时间: 2024-10-18 09:17:56

面试题[后缀数组]: 最长重复子串的相关文章

POJ 1743 Musical Theme 后缀数组 最长重复不相交子串

Musical ThemeTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1743 Description A musical melody is represented as a sequence of N (1<=N<=20000)notes that are integers in the range 1..88, each representing a key on the piano. It

POJ 2217 (后缀数组+最长公共子串)

题目链接: http://poj.org/problem?id=2217 题目大意: 求两个串的最长公共子串,注意子串是连续的,而子序列可以不连续. 解题思路: 有个炒鸡快的O(n)的Manacher算法.不过只能求裸的最长公共和回文子串. 后缀数组解法是这类问题的模板解法. 对于n个串的最长公共子串,这要把这些串连在一起,中间用"$"这类的特殊符号分隔一下. 先求后缀数组,再求最长公共前缀,取相邻两个且属于不同串的sa的最大LCP即可. 原理就是:这样把分属两个串的LCP都跑了一遍,

POJ - 3261 Milk Patterns (后缀数组求可重叠的 k 次最长重复子串)

Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular pattern

POJ 3261 可重叠的 k 次最长重复子串【后缀数组】

这也是一道例题 给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠.算法分析:这题的做法和上一题差不多,也是先二分答案,然后将后缀分成若干组.不同的是,这里要判断的是有没有一个组的后缀个数不小于 k.如果有,那么存在k 个相同的子串满足条件,否则不存在.这个做法的时间复杂度为 O(nlogn). Source Code: //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include

自己写的一个后缀树算法查找一个字符串的最长重复子串

在上个星期面试一家公司的笔试题上面的最后一道题就是写程序查找一个字符串的最长重复子串.当时想了很长时间没想出什么好方法,就把一个算法复杂度比较高的算法写上去了.回来上机把那个算法写了一遍测试没问题,然后自己又到网上面查查还有什么方法,然后发现好像有种叫做后缀树的方法,然后看那个方法,当时没给出代码,看图看了老半天加之自己想了好几个小时终于知道后缀树是个什么东西.然后自己萌生了一个自己写一个后缀树算法解决那个重复子串的问题.然后写了一天终于写出来了.后续有做了一些测试,发现自己写的一个只有几十个字

最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和

参考:http://www.ahathinking.com/archives/124.html 最长公共子序列 1.动态规划解决过程 1)描述一个最长公共子序列 如果序列比较短,可以采用蛮力法枚举出X的所有子序列,然后检查是否是Y的子序列,并记录所发现的最长子序列.如果序列比较长,这种方法需要指数级时间,不切实际. LCS的最优子结构定理:设X={x1,x2,……,xm}和Y={y1,y2,……,yn}为两个序列,并设Z={z1.z2.……,zk}为X和Y的任意一个LCS,则: (1)如果xm=

[算法]最大连续子数组和,最长重复子串

这两道题是我在面试中亲身经历的,在面试滴滴的过程中,我遇到过最大子数组和,在面试阿里的过程中,我遇到过最长重复子串. 1. 最大子数组和 比如,给定一个数组, 1, -2, 3, -4, 5, 6, -7 应该输出, 11. public static int maxSubArray(int[] arr) { int max = Integer.MIN_VALUE; int k = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) {

字符串中连续出现最多的子串 &amp; 字符串中最长重复子串

字符串中连续出现最多的子串 & 字符串中最长重复子串 字符串中连续出现最多的子串 & 字符串中最长重复子串,这两个问题都可以用后缀数组来表示,至于后缀数组可以参考编程珠玑P156:后缀数组就是定义一个数组指针,分别指向字符串中的对应位置,如下: a b c a b c a b c d e .substr[0] b c a b c a b c d e ....substr[1] c a b c a b c d e .......substr[2] a b c a b c d e ......

最长重复子串(可重叠)

首先这是一个单字符串问题.子字符串R 在字符串L 中至少出现两次,则称R 是L 的重复子串.重复子串又分为可重叠重复子串和不可重叠重复子串,这里只是简单讨论最长可重叠的重复子串.首先,最直接的方法就是子串和子串间相互比较,这样查看所有的子串对,时间复杂度为O(n^2).最快的方法是使用后缀数组,如果子串R在L中重复出现,则R至少是L的两个后缀数组的前缀,后缀数组最难的就是如何构建后缀数组,网上有很多博客讨论了相关的算法,这里只是简单的使用排序算法,为的只是理解思想: #include<iostr