leetcode题目:28. 实现 strStr()
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = “hello”, needle = “ll”
输出: 2
示例 2:
输入: haystack = “aaaaa”, needle = “bba”
输出: -1
思路
本题是KMP经典题目。
KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
因此本题主要思路为:构造模式串needle的next数组,然后遍历主串haystack进行匹配,当出现不匹配字符时通过next数组进行回溯。
C++代码
class solution
{
public:
void getNext(int* next, const string& s)
{
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++; //前后缀相等i,j同时后移
next[i] = j; //将前缀长度赋给next[i]
}
}
int strStr(string haystack, string needle)
{
//如果模式串长度为0, 则返回0
if (needle.size() == 0) return 0;
//构造next数组
int next[needle.size()];
getNext(next, needle);
//下面开始匹配
int j = -1; //因为next数组记录的起始位置为1, 因此这里也要同步
for (int i = 0; i < haystack.size(); i++)
{
//不匹配情况,模式串位置需要回溯
while (j >= 0 && needle[j + 1] != haystack[i])
{
j = next[j];
}
//匹配时i,j同时后移
if (haystack[i] == needle[j + 1])
{
j++;
}
//和构造next时不同的是我们不用再更新next数组,而是判断模式串是否匹配完成
if (j == (needle.size() - 1))
{
//匹配完成时j指向needle最后一个字符,i指向needle在haystack中的最后一个字符。
//返回needle在haystack中出现的第一个位置
return (i - needle.size() + 1);
}
return -1;
}
}
};
原文:https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0028.%E5%AE%9E%E7%8E%B0strStr.md
公众号:代码随想录