LeetCode 28. Implement strStr()
Brute Force做的话,时间复杂度 O(mn),考虑有没有更好的方法。
方法一:Rabin-Karp
把needle hash一下,然后对与needle相同长度的在haystack的字符串hash一下,如果hash值相等,就找到了。
期中精髓就是,这个hash如何选择。最好的方法是使用 rolling hash,之前能通过之前计算hash值很快计算下一个hash值。
h(s[0:n-1]) = a^0*s[0] + a^1*s[1] + ... a^n-1*s[n-1]
class Solution { public: const int a=3; // must be a prime // Rabin-Karp // rolling hash: h(s[0:n-1]) = a^0*s[0] + a^1*s[1] + ... a^n-1*s[n-1] int strStr(string haystack, string needle) { int h_size=haystack.size(), n_size=needle.size(); if (needle=="") return 0; if (haystack=="" || h_size<n_size) return -1; int hash_needle=0, hash_cur=0; for (int i=0;i<n_size;++i){ hash_needle = hash_needle + pow(a,i) * f(needle[i]); hash_cur = hash_cur + pow(a,i) * f(haystack[i]); } if (hash_needle==hash_cur) return 0; for (int i=n_size;i<h_size;++i){ hash_cur = (hash_cur-f(haystack[i-n_size]))/a + pow(a,n_size-1) * f(haystack[i]); if (hash_cur==hash_needle) return i-n_size+1; } return -1; } int f(char ch){ return ch-'a'; } };
代码无法AC,因为有长的needle,这样hash值太大就溢出了。别的语言应该能AC,C++的话还要相应修改。
Time Complexity: O(m+n)
方法二:KMP