leetcode 28:Implement strStr()

来源:互联网 发布:身高172扣篮知乎 编辑:程序博客网 时间:2024/06/11 01:00
题目:


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,居然上面快哈。

不过,这与测试字符串有关,若按平均时间来看的话,肯定是下面的更优。

0 0
原创粉丝点击