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

 

posted @ 2018-12-05 05:31  約束の空  阅读(131)  评论(0编辑  收藏  举报