关闭

#leetcode#Implement strStr()

标签: leetcode
361人阅读 评论(0) 收藏 举报
分类:

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.


这题brute force肯定要bug free, 如果能打出来O(n)的解法肯定加分, rolling hash解法必须掌握

下面的解法用3做base,Integer范围内不会溢出, 但是还是用Robin Karp的方法取余比较好, EPI上有这题的解法, 参悟一下再来update。

// https://jixiangsanbao.wordpress.com/2014/04/26/implement-strstr/
// http://blog.csdn.net/linhuanmars/article/details/20276833
public class Solution {
    public int strStr(String haystack, String needle) {
        if(haystack == null || needle == null || needle.length() == 0){
            return 0;
        }
        if(haystack.length() < needle.length()){
            return -1;
        }
        int base = 3; // 如果用大的base, 比如 7 或者 29, 31, 数值太大会溢出, 导致hash计算不对
        // 比较细心的朋友可能看出来了,这个方法的hashcode比较容易越界,因为以素数为底的幂会很大,解决的办法可以用BigInteger,或者如同Rabin–Karp algorithm - Wikipedia一样对于hashcode进行取余,但是可能存在多个字符串映射到同一hashcode的问题,尽管是很少数的情况。

        int neeHash = getHash(needle, 0, needle.length() - 1, base);
        int hayHash = getHash(haystack, 0, needle.length() - 1, base);
        
        for(int i = 0; i <= haystack.length() - needle.length(); i++){
            // verify if collision
            if(hayHash == neeHash){
                if(haystack.substring(i, i + needle.length()).equals(needle)){
                    return i;
                }
            }
            // calculate new hash
            if(i != haystack.length() - needle.length()){
                hayHash -= ((int)(haystack.charAt(i))) * Math.pow(base, needle.length() - 1);
                hayHash *= base;
                hayHash += (int)(haystack.charAt(i + needle.length()));
            }
        }
        
        return -1;
    }
    
    private int getHash(String s, int start, int end, int base){
        int res = 0;
        int k = end - start;
        for(int i = start; i <= end; i++){
            char c = s.charAt(i);
            res += ((int)c) * Math.pow(base, k--);
        }
        return res;
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:54088次
    • 积分:1555
    • 等级:
    • 排名:千里之外
    • 原创:99篇
    • 转载:15篇
    • 译文:0篇
    • 评论:0条