int strStr(char *haystack, char *needle) {
// 外層循環 m 次 (haystack 長度)
// 內層 while 最多 n 次 (needle 長度)
// 總時間 O(m * n)
}
LeetCode 測例包含極端情況:haystack = "aaaa...aaaa" (10^5), needle = "aaaa...aaab" (10^5) → 每次內層匹配到最後一個字符失敗,**實際操作次數 ≈ 10^10**,遠超 1-2 秒限制。
| 算法 | 時間複雜度 | 空間複雜度 | 實現難度 | 推薦度 |
|---|---|---|---|---|
| 暴力匹配 | O(mn) | O(1) | 低 | ❌ TLE |
| KMP (Knuth-Morris-Pratt) | O(m + n) | O(n) | 中 | ✅ **標準答案** |
| Boyer-Moore / Sunday | O(m + n) 平均,最壞 O(mn) | O(σ) | 中高 | ✅ 實際常更快 |
| Rabin-Karp (雙哈希) | O(m + n) 平均 | O(1) | 中 | ✅ 易擴展多模式 |
C++ strstr / Java indexOf |
庫實現通常優化過 | - | 極低 | ⚠️ 面試通常不允許 |
vector buildLPS(const string& pat) {
int n = pat.size();
vector lps(n, 0);
for (int i = 1, len = 0; i < n; ) {
if (pat[i] == pat[len]) lps[i++] = ++len;
else if (len) len = lps[len - 1];
else lps[i++] = 0;
}
return lps;
}
int strStr(string haystack, string needle) {
if (needle.empty()) return 0;
auto lps = buildLPS(needle);
for (int i = 0, j = 0; i < haystack.size(); ) {
if (haystack[i] == needle[j]) { ++i; ++j; }
else if (j) j = lps[j - 1];
else ++i;
if (j == needle.size()) return i - j;
}
return -1;
}
string(100000, 'a') + string(99999, 'a') + 'b'。chrono 計時驗證優化前後差異。haystack.find(needle) (內建優化) 通過,但面試需手寫 KMP。