Implement strStr() – LeetCode 28
Problem
Description
Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
 
Answer
Original
Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | class Solution {public:
 int strStr(string haystack, string needle) {
 if(needle.size() == 0 || haystack.size() == 0) return -1;
 int n_point = 0, result = -1;
 for(unsigned i = 0; i != haystack.size(); ++i){
 if(haystack[i] == needle[0]){
 for(unsigned j = 1; j != needle.size();++j){
 if(needle[j] != haystack[i+j]) break;
 }
 }
 }
 }
 };
 
 | 
思路
目前用的是最简单的暴力法,从头到尾进行比对。构思的时候觉得可以少遍历一些元素,事实证明的确可以,这个问题也被算作“字符串匹配”。时间复杂度$O(n \times m)$,n为haystack长度,m为needle长度,空间复杂度$O(1)$。
耗时$6$ ms,排名$74.57\%$
Better
思路
还可以用Rabin–Karp algorithm算法,比较简单,对一个子串生成HashCode,妙在Hash用的是线性算法。使用29这个素数做底,以这个素数的幂为基。那么对于abc,可以算作$Hash = 1 \times 29^{0} + 2 \times 29^{1} + 3 \times 29^{2}$,则下一步bcd算作$Hash = \frac{Hash}{10} + 4 \times 29^{3}$。时间复杂度$O(n)$,空间复杂度$O(1)$。
耗时$6$ ms,排名$74.57\%$
Code
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | class Solution {public:
 int charToInt(char c) {
 return (int)(c-'a'+1);
 }
 
 int strStr(string haystack, string needle) {
 int m = needle.size();
 int n = haystack.size();
 if (m == 0) return 0;
 if (m > n) return -1;
 
 const int base = 29;
 long long max_base = 1;
 long long needle_code = 0;
 long long haystack_code = 0;
 for (int j = m - 1; j >= 0; j--) {
 needle_code += charToInt(needle[j])*max_base;
 haystack_code += charToInt(haystack[j])*max_base;
 max_base *= base;
 }
 max_base /= base;
 if (haystack_code == needle_code)
 return 0;
 for (int i = m; i < n; i++) {
 haystack_code = (haystack_code - charToInt(haystack[i-m]) * max_base) * base + charToInt(haystack[i]);
 if (haystack_code == needle_code)
 return i - m + 1;
 }
 return -1;
 }
 };
 
 |