[LeetCode] 28. Implement strStr() 解题思路

Implement strStr().

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

问题:实现 strStr() 函数。即在  haystack 中匹配 needle 字符串。

可以理解为,实际上这道题是在问如何实现 KMP(Knuth–Morris–Pratt) 算法。这是个效率比较高的算法,只需要扫一遍 haystack 就可以得到结果,耗时 O(n) 。在扫之前需要做的是对 needle 字符串预处理,得到 needle 各个前缀字符串[0...i]中 既是真实前缀又是真实后缀的子字符串的最长长度。理解这句话,需要注意的是“既是真实前缀又是真实后缀” 是指在某一 needle前缀而言的。

需要详细理解 KMP 算法,可以参考前一篇文章我所理解的 KMP(Knuth–Morris–Pratt) 算法,或许有帮助。

 1 vector<int> LofPS;
 2 
 3 /**
 4  * 求 s 中所有前缀字符串[0...i]各自的 既是真实前缀又是真实后缀的子字符串最长长度,存于 LofPS[i]。
 5  *
 6  * 例如令 len = LofPS[i],则表示 真实前缀s[0...len-1] 和 真实后缀s[ i-len+1...i ] 相等。
 7  *
 8  */
 9 vector<int> computePrefixSuffix(string s){
10     
11     // LofPS[i] 表示 s[0....i] 部分中,既是真实前缀又是真实后缀的子字符串最长长度。
12     vector<int> LofPS(s.size());
13     
14     if (s.size() == 0) {
15         return LofPS;
16     }
17     
18     LofPS[0] = 0;
19     
20     int len = 0;
21     int i = 1;
22     
23     while (i < s.size()) {
24         
25         if (s[i] == s[len]) {
26             len++;
27             LofPS[i] = len;
28             i++;
29             continue;
30         }
31                 
32         if (len != 0) {
33             // 利用之前计算的结果。这里是一个需要理解的点。
34             // 根据已计算的 LofPS[len-1]部分 真实前缀、真实后缀的相等的最长长度,定位同样匹配 s 前缀但是更短的子字符串。
35             len = LofPS[len - 1];
36         }else{
37             LofPS[i] = 0;
38             i++;
39         }
40     }
41     
42     return LofPS;
43 }
44 
45 
46 int strStr(string haystack, string needle) {
47     
48     // 计算 needle 中所有前缀字符串[0...idx]各自的真实前缀且是真实后缀的最长长度。
49     vector<int> tmp(needle.size());
50     LofPS = tmp;
51     
52     LofPS = computePrefixSuffix(needle);    
53     
54     int i = 0 ;
55     int k = 0;
56 
57     while (i < haystack.size() && k < needle.size()) {
58         if (haystack[i] == needle[k]) {
59             i++;
60             k++;
61             continue;
62         }
63         
64         if (LofPS[k-1] != 0) {
65             k = LofPS[k-1];
66             continue;
67         }
68         
69         if (haystack[i] == needle[0]) {
70             k = 1;
71             i++;
72         }else{
73             k = 0;
74             i++;
75         }
76     }
77 
78     if (k == needle.size()) {
79         return i - k;
80     }else{
81         return -1;
82     }
83 }

 

posted @ 2015-12-25 23:51  TonyYPZhang  阅读(429)  评论(0编辑  收藏  举报