思路一:hash(O(m+n)
class Solution {
public:
int strStr(string haystack, string needle) {
int len1 = haystack.size(), len2 = needle.size();
//得到next数组
vector<int> next(len2);
next[0] = -1;
int j = -1;
for (int i = 1; i < len2; ++i) {
while (j != -1 && needle[i] != needle[j + 1]) {
j = next[j];
}
if (needle[i] == needle[j + 1]) j++;
next[i] = j;
}
//字符串匹配
j = -1;
for (int i = 0; i < len1; ++i) {
while (j != -1 && haystack[i] != needle[j + 1]) {
j = next[j];
}
if (haystack[i] == needle[j + 1]) j++;
if (j == len2 - 1) return i - len2 + 1;
}
return -1;
}
};
思路二:字符串hash O(max(m, n))
class Solution {
public:
using ull = unsigned long long;
int strStr(string haystack, string needle) {
//字符串hash
int n = haystack.size(), m = needle.size();
if (m > n) return -1;
ull hash2 = 0;
int base = 131;
for (int i = 0; i < m; ++i) {
hash2 = hash2 * base + (needle[i] - 'a' + 1);
}
vector<ull> hash1(n + 1), pow(n + 1);
pow[0] = 1;
for (int i = 0; i < n; ++i) {
hash1[i + 1] = hash1[i] * base + (haystack[i] - 'a' + 1);
pow[i + 1] = pow[i] * base;
}
auto get = [&](int l, int r) {
return hash1[r] - (hash1[l - 1] * pow[r-l+1]);
};
for (int i = 0; i <= n - m; ++i) {
if (get(i + 1, i + m) == hash2) return i;
}
return -1;
}
};
易错点:
1:防止aa 跟 a 区分不开,因此’a’应该映射到1,因此needle[i] - 'a’要 + 1