28. Implement strStr
Implement strStr().
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example 1:
Input: haystack = "hello", needle = "ll"
Output: 2
Example 2:
Input: haystack = "aaaaa", needle = "bba"
Output: -1
Clarification:
What should we return when needle is an empty string? This is a great question to ask during an interview.
For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strstr() and Java’s indexOf().
方法1: substr
思路:
循环haystack每一个位置,提取长度为n的substring和needle比较。由于只需要返还first occurrence,找到了就可以直接返回。这里的循环终点是m - n + 1,i.e. if m = 5, n = 4, 只需要遍历到i < 2。这个条件可以提速非常多。
class Solution {
public:
int strStr(string haystack, string needle) {
int m = haystack.size();
int n = needle.size();
if (n == 0) return 0;
if (m == 0 || m < n) return -1;
for (int i = 0; i < m - n + 1; i++){
if (haystack.substr(i, n) == needle){
return i;
}
}
return -1;
}
};
方法2:
思路:
手动实现比较,这里的break是break出内层循环,保证外层循环还会继续。
易错点:
如果不符合条件需要break,出内层循环,而不是直接return - 1。才不会出现haystack = “hello”,needle = “lo”,直接返回-1的情况。
class Solution {
public:
int strStr(string haystack, string needle) {
if (needle.empty()) return 0;
int m = haystack.size(), n = needle.size();
if (m < n) return -1;
for (int i = 0; i <= m - n; ++i) {
int j = 0;
for (j = 0; j < n; ++j) {
if (haystack[i + j] != needle[j]) break;
}
if (j == n) return i;
}
return -1;
}
};
方法3: kmp
思路:
易错点:
- 在主函数里,判断是否complete match的地方很critical,如果if (j == n)放的靠前或者考后都会漏掉一些case。比如放在后面会算错"a"和“”。
class Solution {
public:
int strStr(string haystack, string needle) {
int m = haystack.size(), n = needle.size();
if (!n && !m) return 0;
vector<int> lps = kmp(needle);
for (int i = 0, j = 0; i < m;) {
if (haystack[i] == needle[j]) {
i++; j++;
}
if (j == n) return i - j;
if (i < m && haystack[i] != needle[j]) {
if (j == 0) i++;
else j = lps[j - 1];
}
}
return -1;
}
vector<int> kmp(string needle) {
vector<int> lps(needle.size(), 0);
for (int i = 1, j = 0; i < needle.size();) {
if (needle[i] == needle[j]) {
lps[i++] = ++j;
}
else if (j != 0){
j = lps[j - 1];
} else {
lps[i++] = 0;
}
}
return lps;
}
};
kmp: https://www.geeksforgeeks.org/kmp-algorithm-for-pattern-searching/