class Solution {
public:
vector<int> next;
void calc_next(const string &pat) {
int n = pat.size();
next.resize(n);
next[0] = -1;
for (int i = 1; i < n; ++i) {
int j = i - 1;
while (next[j] >= 0 && pat[i] != pat[next[j] + 1]) {
j = next[j];
}
next[i] = pat[i] == pat[next[j] + 1]? next[j] + 1: -1;
}
}
int find(const string &s, const string &pat) {
calc_next(pat);
int n = s.size(), m = pat.size();
if (n < m) {
return -1;
}
int j = 0, i = 0;
for (; i < n && j < m; ++i) {
if (s[i] == pat[j]) {
++j;
} else if (j == 0 || next[j - 1] == -1) {
if (j > 0) {
--i;
}
j = 0;
} else {
--i;
j = next[j - 1] + 1;
}
}
return j < m? -1:i - m;
}
int strStr(string haystack, string needle) {
if (needle.empty()) {
return 0;
}
return find(haystack, needle);
}
};