1044. 最长重复子串

给出一个字符串 S,考虑其所有重复子串(S 的连续子串,出现两次或多次,可能会有重叠)。

返回任何具有最长可能长度的重复子串。(如果 S 不含重复子串,那么答案为 “”。)

示例 1:

输入:“banana”
输出:“ana”
示例 2:

输入:“abcd”
输出:""

提示:

2 <= S.length <= 10^5
S 由小写英文字母组成。

二分法+滚动哈希 1344ms

class Solution {
public:
    const long long mod = LLONG_MAX / 27;
    string longestDupSubstring(string S) {
        vector<int> p((int)S.length());
        for(int i = 0; i < S.length(); ++i)
            p[i] = S[i]-'a'+1;
        int l = 1, r = (int)S.length()-1, ans = 0, d = 0;
        while(l <= r)
        {
            int mid = (l+r) >> 1;
            if (check(p, mid, d))
            {
                ans = mid;
                l = mid+1;
            }else r = mid-1;
        }
        return S.substr(d, ans);
    }
    
    bool check(const vector<int> &p, int m, int &d)
    {
        int n = (int)p.size();
        unordered_set<long long> q;
        long long t = 0,h=1;
        int a=27;
        for(int i = 0; i < m; ++i)
        {
            h = (h*a)%mod;
            t = (t*a%mod + p[i])%mod;
        }
        q.insert(t);
        for(int i = m; i < n; ++i)
        {
            t = ((t*a%mod + p[i])%mod - p[i-m]*h%mod + mod)%mod;
            if (q.count(t) > 0)
            {
               d=i-m+1;
               return true;
            }
            q.insert(t);
        }
        return false;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_42054167/article/details/93356986