题解 | #最长重复子串 -- 字符串哈希#

最长重复子串

http://www.nowcoder.com/practice/4fe306a84f084c249e4afad5edf889cc

字符串哈希

这题与 LeetCode 1044 最长重复子串 类似,
不同的是,这里的子串的首尾相连,那么根据力扣这题的思路,可以计算前后长度为L的[i, i + L - 1]和[i + L, i + 2 * L - 1]的字符串哈希值,然后判断这个哈希值是否相等,如果相等说明,存在;
时间复杂度:,题目要求是C++ 5s,不会超时哈!
空间复杂度:

class Solution {
public:
    typedef unsigned long long ULL;
    const ULL MOD = pow(2, 48);
    bool helper(const string& s, int L){ //返回下标
        int n = s.length();
        ULL secret[2] = {0, 0};
        ULL factor = 1;
        const ULL BASE = 131;
        for(int i = 0; i < L; i ++){
            secret[0] = (((secret[0] % MOD) *  BASE ) % MOD + s[i] - 'a') % MOD;
            secret[1] = (((secret[1] % MOD) *  BASE ) % MOD + s[i + L] - 'a') % MOD;
            if(i > 0) factor = (factor % MOD) * BASE % MOD;
        }
        if(secret[0] == secret[1]) return true;
        for(int i = L; i + L <= n; i ++){
            secret[0] = (secret[0] % MOD - (factor % MOD * (s[i - L] - 'a') % MOD) + MOD) % MOD;
            secret[0] = ((secret[0] % MOD * BASE) % MOD + s[i] - 'a') % MOD;
            secret[1] = (secret[1] % MOD - (factor % MOD * (s[i] - 'a') % MOD) + MOD) % MOD;
            secret[1] = ((secret[1] % MOD * BASE) % MOD + s[i + L] - 'a') % MOD;
            if(secret[0] == secret[1]) return true;
        }
        return false; //不存在重复子串
    }
    int solve(string a) {
        // write code here
        int n = a.length();
        int L = n / 2;
        while(L > 0){
            if(helper(a, L)) return 2 * L;
            L --;
        }
        return 0;
    }
};
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-09 16:15
我应届生,去年10月份开始在这家公司实习,到今年10月份正好一年想(实习+试用期),在想要不要提前9月份就离职,这样好找工作些,但又差一个月满一年,又怕10月份国庆回来离职,容易错过了下半年的金九银十,到年底容易gap到年后
小破站_程序员YT:说这家公司不好吧,你干了快一年 说这家公司好吧,你刚毕业就想跑路说你不懂行情吧,你怕错过金九银十说 你懂行情吧,校招阶段在实习,毕业社招想换工作 哥们,我该怎么劝你留下来呢
应届生,你找到工作了吗
点赞 评论 收藏
分享
Yki_:你要算时间成本呀,研究生两三年,博士三四年,加起来就五六年了,如果你本科去腾讯干五年,多领五年的年薪,加上公司内涨薪,可能到时候十五年总薪资也跟博士差不多
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务