Leetcode | Implement strStr()
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
此題我覺得并不是真要你寫出kmp算法。 指針暴力法我覺得可能是考察點。而且要accept的話,必須要忽略后面一段不可能匹配的串。指針的操作要非常小心。
Of course, you can demonstrate to your interviewer that this problem can be solved using known efficient algorithms such as?Rabin-Karp algorithm,?KMP algorithm, and the?Boyer-Moore algorithm. Since these algorithms are usually studied in advanced algorithms class, for an interview it is sufficient to solve it using the most direct method — The?brute force method.
非指針代碼很好小,很難有錯。最長掃描n1-n2+1個就夠了。
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) { 4 if (haystack == NULL || needle == NULL) return NULL; 5 int n1 = strlen(haystack); 6 int n2 = strlen(needle); 7 int j; 8 9 for (int i = 0; i < n1 - n2 + 1; ++i) { 10 j = 0; 11 while (j < n2 && needle[j] == haystack[i + j]) j++; 12 if (j == n2) return haystack + i; 13 } 14 return NULL; 15 } 16 };c指針代碼:
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) { 4 if (haystack == NULL || needle == NULL) return NULL; 5 if (*needle == '\0') return haystack; 6 char *ph = haystack, *pn = needle, *count = ph, *tmp; 7 while (*pn) { 8 if (!*count) return NULL; 9 pn++; 10 count++; 11 } 12 if (*needle) count--; 13 while (*count) { 14 pn = needle; 15 tmp = ph; 16 while (*pn && *tmp && *pn == *tmp) { 17 pn++; tmp++; 18 } 19 if (!*pn) return ph; 20 ph++; 21 count++; 22 } 23 24 return NULL; 25 } 26 };如果是needle是空串,返回應該是haystack整個串。
最長掃描n1-n2+1個就夠了。所以要讓count循環m-1次。優化后的代碼如下:
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) { 4 if (*needle == '\0') return haystack; 5 char *ph = haystack, *pn = needle, *count = ph, *tmp; 6 while (*++pn) { 7 if (!*count) return NULL; 8 count++; 9 } 10 while (*count) { 11 pn = needle; 12 tmp = ph; 13 while (*pn && *tmp && *pn == *tmp) { 14 pn++; tmp++; 15 } 16 if (!*pn) return ph; 17 ph++; 18 count++; 19 } 20 21 return NULL; 22 } 23 };?kmp算法的話,直接看wiki就好。看完也實現一遍。
Partial match 數組里面存的是當前位置的前綴等于整個匹配串的某個前綴。
比如"ABCDABC",第二個B(紅色)對應的值就是1(綠色).?
匹配失敗后,假設haystack的當前位置是i,匹配到i+j失敗了,假設就匹配到第二個B失敗。那么就要j就要指向第一個B那里,然后i就要跳到第二個A,也就是i = i + j - P[j].
1 class Solution { 2 public: 3 char *strStr(char *haystack, char *needle) { 4 if (haystack == NULL || needle == NULL) return NULL; 5 if (*needle == '\0') return haystack; 6 7 int n1 = strlen(haystack), n2 = strlen(needle), count = 0; 8 vector<int> kmp(n2, 0); 9 kmp[0] = -1; 10 11 for (int i = 2; i < n2; ) { 12 if (needle[i - 1] == needle[count]) { 13 count++; 14 kmp[i++] = count; 15 } else if (count > 0) { 16 count = kmp[count]; 17 } else { 18 kmp[i++] = 0; 19 } 20 } 21 22 for (int i = 0, j = 0; i + j < n1; ) { 23 if (haystack[i + j] == needle[j]) { 24 j++; 25 if (j == n2) return haystack + i; 26 } else if (kmp[j] > 0) { 27 i = i + j - kmp[j]; 28 j = kmp[j]; 29 } else { 30 j = 0; 31 i++; 32 } 33 } 34 35 return NULL; 36 } 37 };前面也有摘過KMP算法。
建立表的算法的復雜度是 O(n),其中 n 是 W 的長度。除去一些初始化的工作,所有工作都是在 while 循環中完成的,足夠說明這個循環執行用了 O(n) 的時間,同時還會檢查 pos 和 pos - cnd 的大小。在第一個分支里,pos - cnd 被保留,而 pos 與 cnd 同時遞增,自然,pos 增加了。在第二個分支里,cnd 被 T[cnd] 所替代,即以上總是嚴格低于 cnd,從而增加了 pos - cnd。在第三個分支里,pos 增加了,而 cnd 沒有,所以 pos 和 pos - cnd 都增加了。因為 pos ≥ pos - cnd,即在每一個階段要么 pos 增加,要么 pos 的一個下界增加;所以既然此算法只要有 pos = n 就終止了,這個循環必然最多在 2n 次迭代后終止, 因為 pos - cnd 從 1 開始。因此建立表的算法的復雜度是 O(n)。
轉載于:https://www.cnblogs.com/linyx/p/3728708.html
總結
以上是生活随笔為你收集整理的Leetcode | Implement strStr()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基本shell编程【3】- 常用的工具a
- 下一篇: c++ list sort