【LeetCode】28. 找出字符串中第一个匹配项的下标
题意:给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
思路:字符串匹配考察KMP算法,重点利用最长相等前后缀求出Next数组,然后主串指针永远向前,字串利用Next数组回退比较。
代码:
class Solution {
public:
void getNext(vector<int> &next, const string &str)
{
// 1.初始化,i表示后缀,j表示前缀
int j = 0;
next[0] = 0;
for (int i = 1; i < str.size(); ++i)
{
// 2.不相等情况,查已经求过的表
while (j > 0 && str[i] != str[j])
{
j = next[j - 1];
}
// 3.相等情况往后走
if (str[i] == str[j])
{
++j;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
// next[idx]表示idx结尾的字符串最长相等前后缀的长度是多少,若从0开始值就等于下标
vector<int> next(needle.size());
getNext(next, needle);
// 遍历主串,移动子串
for (int i = 0, j = 0; i < haystack.size(); ++i)
{
while (j > 0 && haystack[i] != needle[j])
{
j = next[j - 1];
}
if (haystack[i] == needle[j])
{
++j;
}
if (j == needle.size())
{
return (i - needle.size() + 1);
}
}
return -1;
}
};
【LeetCode】459.重复的子字符串
题意:给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
思路:将字符串s再拷贝一次,排除首尾,内部包含s自己就肯定可以由子串重复构成
代码:
class Solution {
public:
void getNext(vector<int> &next, const string &str)
{
next[0] = 0;
int j = 0;
for (int i = 1; i < str.size(); ++i)
{
while (j > 0 && str[i] != str[j])
{
j = next[j - 1];
}
if (str[i] == str[j])
{
++j;
}
next[i] = j;
}
}
bool repeatedSubstringPattern(string s) {
string str = s.substr(1) + s;
str.pop_back();
// 下面使用KMP算法
vector<int> next(s.size());
getNext(next, s);
for (int i = 0, j = 0; i < str.size(); ++i)
{
while (j > 0 && str[i] != s[j])
{
j = next[j - 1];
}
if (str[i] == s[j])
{
++j;
}
if (j == s.size())
{
return true;
}
}
return false;
}
};
心态:“第四章 字符串part02” 拿下!
参考资料