Implement strStr()
要点:rolling hash方法的速度比较慢。
小优化:不用hash%base,而用hash-=base*最高位是一样的。
rolling hash错误点:
- base的连乘少一位,另外别搞成/10
- python应该是ord(c)-ord(‘a’),不是ord(c)
- 以i结尾的start index是i-nlen+1,不是i-nlen,实际就是把len和start index在公式中置换一下,所以有+1
- 开始初始化haystack hash的时候长度是needle len,不要弄混成初始化needle
- 如果haystack没有needle长,提早返回-1
class Solution(object):
def strStr(self, haystack, needle):
"""
:type haystack: str
:type needle: str
:rtype: int
"""
nlen, hlen = len(needle), len(haystack)
if nlen==0:
return 0
if hlen<nlen: # error 1:
return -1
gethash = lambda x: ord(x)-ord('a')
rolling = lambda x,y: x*26+y
nhash = reduce(rolling, map(gethash, needle))
hhash = reduce(rolling, map(gethash, haystack[:nlen]))
if nhash==hhash:
return 0
base = 26**(nlen-1)
for i in xrange(nlen, hlen):
hhash-=base*gethash(haystack[i-nlen])
hhash=hhash*26+gethash(haystack[i])
if hhash==nhash:
return i-nlen+1
return -1