题目:找出字符串中第一个匹配项的下标
描述:
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = “sadbutsad”, needle = “sad”
输出:0
解释:“sad” 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
leetcode链接
方法一:暴力匹配
该题为字符串匹配算法,直接暴力匹配,返回匹配成功的首个字母下标
时间复杂度:o(mn) m,n分别为主串字串的长度
空间复杂度:o(1)
int strStr(string haystack, string needle) {
for(int i=0;i<haystack.size();i++){
int k=0;
while(true){
if(haystack[i+k]==needle[k]){
k++;
}else{
break;
}
if(k==needle.size()){
return i;
}
}
}
return -1;
}
方法二:KMP算法
KMP算法的思路是当我们匹配失败的时候,不会去移动我们的主串指针,而是移动子串指针移动到特定的位置,再去进行比较,而这个特定的位置就保存在next数组中。什么是next数组呢,next[i]表示当匹配到第i个位置失败的时候,我们子串指针需要移动到的位置,因此我们KMP算法的主串指针是不会回溯的,因此整个算法的时间复杂度为o(n),下面讲解如何求解next数组:
时间复杂度:o(n)
空间复杂度:o(m) m为子串的长度
int strStr(string haystack, string needle) {
int n = haystack.size(),m = needle.size();
int i=0,j=0;
int* next=getNext(needle);
for (int i = 0, j = 0; i < n; i++) {
while (j > 0 && haystack[i] != needle[j]) {
j = next[j];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == m) {
return i - m + 1;
}
}
return -1;
}
int* getNext(string needle){
int* next = new int[needle.size()];
next[0] = -1; //while the first char not match, i++,j++
int j = 0;
int k = -1;
while (j < needle.size() - 1)
{
if (k == -1 || needle[j] == needle[k])
{
j++;
k++;
next[j] = k;
}
else
{
k = next[k];
}
}
return next;
}