您的位置:首页 > 其它

leetcode 28:Implement strStr()

2015-10-12 20:38 405 查看
题目:

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

思路:

题目大意是让我们找到needle字符串在haystack字符串中第一次出现的位置。这就是字符串的模式匹配问题。

朴素的模式匹配算法是对主串的每一个字符作为子串开头,与要匹配的字符进行匹配。对主串做大循环,每个字符开头做T的长度的小循环,知道匹配成功或全部遍历完成为止。

时间复杂度为O(n*m),显然效率太低。

我们可以用KMP算法来实现,这样可以避免每次检测到不同时回溯到子字符串的开始。具体实现如下:

class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2,0);
NEXT(next, needle);
int i=0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}

void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j]) next[++i] = ++j;
else j = next[j];
}
}
};

算法分析请参考本人的另一篇博文:http://blog.csdn.net/onlyou2030/article/details/49078311

在上述博文中提到了改进的KMP算法,对于较长的连续字符的字符串有较好的提高效率的作用。改动的只是求next函数。

class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2, 0);
NEXT(next, needle);
int i = 0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}

void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j])
if (needle[++i] == needle[++j]) next[i] = next[j]; // 当两个字符相等时要跳过
else next[i] = j;
else j = next[j];
}
}
};

奇怪的是,上面的解法8ms,下面的解法12ms,居然上面快哈。
不过,这与测试字符串有关,若按平均时间来看的话,肯定是下面的更优。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: