题目:实现 strStr() 函数。给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
示例 1:
输入:haystack = “hello”, needle = “ll”
输出:2
示例 2:
输入:haystack = “aaaaa”, needle = “bba”
输出:-1
思路:
方法一:暴力解法,首先在haystack里面找和needle[0]相等的字符,找到了就继续判断之后的字符是否相等。时间复杂度为O(n*m)。
代码:
class Solution { //实现strStr()函数
public:
int strStr(string haystack, string needle) {
if (needle.size() == 0)
return 0;
for (int i = 0; i < haystack.size();i++) {
if (haystack[i] == needle[0]) {
int j = i + 1;;
int k = 1;
while (j < haystack.size() && k < needle.size() && haystack[j] == needle[k]){
j++;
k++;
}
if (k == needle.size())
return i;
}
}
return -1;
}
};
int main() {
string haystack = "mississippi";
string needle = "issip";
Solution solution;
int result = solution.strStr(haystack, needle);
printf("%d\n", result);
return 0;
}
方法二:使用KMP算法。实现一个needle字符串的前缀表。当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
代码随想录里面对KMP做了非常详细的介绍,有兴趣可以查看代码随想录实现strStr。时间复杂度为O(n+m)。
代码:
class Solution { //实现strStr()函数 KMP
public:
void getNext(vector<int>& next, string const& s) { //统一减1的前缀表
int j = -1;
next[0] = j;
for (int i = 1; i < s.size(); ++i) {
while (j >= 0 && s[i] != s[j + 1]) { //前后缀不同,回退
j = next[j];
}
if (s[i] == s[j + 1]) { //找到相同的前后缀
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if (needle.size() == 0) {
return 0;
}
vector<int> next(needle.size());
getNext(next, needle);
int j = -1;
for (int i = 0; i < haystack.size(); ++i) {
while (j >= 0 && haystack[i] != needle[j + 1]) {
j = next[j];
}
if (haystack[i] == needle[j + 1]) {
j++;
}
if (j == (needle.size() - 1)) {
return (i - needle.size() + 1);
}
}
return -1;
}
};
int main() {
string haystack = "aabaabaafa";
string needle = "aabaaf";
Solution solution;
int result = solution.strStr(haystack, needle);
printf("%d\n", result);
return 0;
}