字符串哈希

1、字符串匹配:实现 strStr()    (当KMP用)

typedef unsigned long long ull;
ull p[100000], pre[100000];
class Solution {
public:
    ull get(int l, int r) {
        return pre[r] - pre[l - 1] * p[r - l + 1];
    }
    int strStr(string s, string needle) {
        if (s.size() < needle.size()) return -1;
        if (s == needle) return 0;
        memset(p, 0, sizeof p);
        memset(pre, 0, sizeof pre);
        ull base = 13331;
        int n = s.size(), m = needle.size();
        p[0] = 1;
        for (int i = 0; i < n; i++) {
            p[i + 1] = p[i] * base;
            pre[i + 1] = pre[i] * base + s[i] - 'a' + 1;
        }
        ull nee = 0;
        for (char x : needle) nee = nee * base + x - 'a' + 1;
        for (int i = 1; i <= s.size(); i++) {
            if (get(i, i + m - 1) == nee) return i - 1;
        }
        return -1;
    }
};

2、求最长回文子串:最长回文子串

class Solution:
    def longestPalindrome(self, s: str) -> str:
        p, hl, hr = [0] * 1005, [0] * 1005, [0] * 1005
        p[0] = 1
        base, mod = 131, 2**64+1
        res = [0, 0]

        def getl(l, r):
            return (hl[r] - hl[l - 1] * p[r - l + 1]) % mod
        def getr(l, r):
            return (hr[l] - hr[r + 1] * p[r - l + 1]) % mod

        for i in range(len(s)):
            p[i + 1] = (p[i] * base) % mod
            hl[i + 1] = (hl[i] * base + ord(s[i])) % mod
        for i in range(len(s) - 1, -1, -1):
            hr[i] = (hr[i + 1] * base + ord(s[i])) % mod

        for i in range(len(s)):
            l, r = 0, min(i, len(s) - i - 1)
            while l < r:
                m = l + r >> 1
                if getl(i + 1 - m, i + 1) == getr(i, i + m):
                    l = m + 1
                else:
                    r = m
            if getl(i + 1 - l, i + 1) != getr(i, i + l):
                l -= 1
            if i + l - (i - l) > res[1] - res[0]:
                res[0] = i - l
                res[1] = i + l
                
        for i in range(len(s)):
            l, r = 0, min(i, len(s) - i)
            while l < r:
                m = l + r >> 1
                if getl(i - m, i) == getr(i, i + m):
                    l = m + 1
                else:
                    r = m
            if i + l - (i - l) > res[1] - res[0]:
                res[0] = i - l
                res[1] = i + l - 1

        return s[res[0]:res[1] + 1]

3、求最长公共子路径:最长公共子路径

import collections
class Solution:
    def longestCommonSubpath(self, n: int, paths: List[List[int]]) -> int:
        p = [1] * 100001
        h = [0] * 100001
        base = 133331
        mod = 2 ** 64 - 1
        def get(l, r):
            return (h[r] - h[l - 1] * p[r - l + 1]) % mod
        def check(m):
            c = collections.Counter()
            for v in paths:
                used = set()
                for i in range(len(v)):
                    p[i + 1] = (p[i] * base) % mod
                    h[i + 1] = (h[i] * base + v[i]) % mod
                for i in range(len(v) - m + 1):
                    x = get(i + 1, i + m)
                    if x not in used:
                        used.add(x)
                        c[x] += 1
            return max(c.values()) == len(paths)

        l, r = 1, min(len(i) for i in paths) + 1
        while l < r:
            m = l + r >> 1
            if check(m):
                l = m + 1
            else:
                r = m
        return l - 1

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值