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