Leetcode: strStr()

Implement strStr().

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

分析:该题是经典的串匹配,我们可以用KMP来解,时间复杂度为O(m+n)。关于KMP的详细内容可以参考一下博文http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html。这里,我主要介绍一下运用KMP的几个关键点。

1. 为了避免指针回溯,KMP引入了next数组,用来确定下次匹配时模式串指针的位置。在用next数组前,我们要知道next[j]的含义,便于我们理解和实现。通俗的讲,next[j]表示pattern[0,j-1]中其前缀跟后缀相同的最大长度,我们用下面的式子来帮助理解:

next[0] = -1, next[1] = 0; for j > 1, next[j] = max(k) where  0<k<j and pattern[0,k-1] = pattern[j-k, j-1]。

2. 如何计算next数组,我们可以用动态规划的思想来计算next数组,在计算next[j]时,如果pattern[j-1] = pattern[next[j-1]],那么next[j] = next[j-1] + 1; 否则不匹配,则可以按KMP的做法,用next[j-1]确定下一个匹配的位置(此时模式串和目标串都是pattern[0,j-1])。

3. 在解决上面两个问题后,我们讨论如果通过next数组来做串匹配。在串匹配的时候可分两种情况:

  1) target[i] = pattern[j],说明匹配,我们只需i++, j++。

  2)target[i] != pattern[j], 此时我们需要用next数组确定j的下一个匹配位置。如果next[j] >= 0,则 j = next[j],i位置不便; 如果next[j] == -1,i往后移一步,j置0。

      在实现时,2)中next[j] = -1的情况可以跟1)的情况合并。

解决了上面三个讨论,我们就可以写出KMP代码了,如下:

 1 class Solution {
 2 public:
 3     char *strStr(char *haystack, char *needle) {
 4         return kmp(haystack, needle);
 5     }
 6     char * kmp(char * haystack, char * needle){
 7         int m = strlen(needle);
 8         if(m == 0) return haystack;
 9         int * next = (int *)malloc(sizeof(int) * m);
10         
11         compute_next(needle, next);
12         int i = 0, k = 0;
13         
14         while(i < strlen(haystack)){
15             if(k == -1 || haystack[i] == needle[k]){
16                 k++;
17                 i++;
18             }else k = next[k];
19             if(k == m) return haystack+i-m;
20         }
21         return NULL;
22     }
23     void compute_next(char * needle, int * next){
24         int m = strlen(needle);
25         next[0] = -1;
26         int k = -1;
27         for(int j = 0; j < m-1;){
28             if(k == -1 || needle[j] == needle[k]){
29                 k++;
30                 j++;
31                 next[j] = k;
32             }else k = next[k];
33         }
34     }
35 };

 

posted on 2014-12-05 15:40  Ryan-Xing  阅读(206)  评论(0编辑  收藏  举报