class Solution:
def strStr(self, haystack: str, needle: str)->int:for i in range(len(haystack)-len(needle)+1):#ifhaystack[i:i+len(needle)]== needle:for j in range(len(needle)):if haystack[i+j]!= needle[j]:breakelse:if j <len(needle)-1:continueelse:return i
return-1
二 RK算法 利用hashmap
class Solution:
def strStr(self, haystack: str, needle: str)->int:'''RK算法 利用hashmap'''
def hash_(s,start,end):'''每一位ascii码相加'''
assert start <= end
res =0for c in s[start:end+1]:
res +=ord(c)return res
n =len(haystack)
m =len(needle)if n <= m:return0if haystack==needle else-1#n-m+1个子串
hash_map =[0]*(n-m+1)
hash_map[0]=hash_(haystack,0,m-1)for i in range(1,n-m+1):#i-1 i i+1... i+m-2#ii+1... i+m-2 i+m-1
hash_map[i]= hash_map[i-1]-hash_(haystack,i-1,i-1)+hash_(haystack,i+m-1,i+m-1)
# 模式串hash
hash_p =hash_(needle,0,m-1)
# 匹配
for i in range(n-m+1):if hash_map[i]== hash_p:if haystack[i:i+m]== needle:return i
else:continuereturn-1
三、KMP算法
class Solution:
def strStr(self, haystack: str, needle: str)->int:'''KMP算法'''
n =len(haystack)
m =len(needle)if n<=m:return0if haystack == needle else-1
next_ = self.get_next(needle)
j =0for i in range(n):
# 向前遍历,直到不相等回退,所有的i,所有的j 提前找到提前返回
while j >0 and haystack[i]!= needle[j]:
# 移到公共前后缀的前缀后方,直到相等
j = next_[j-1]+1if haystack[i]== needle[j]:if j == m-1:return i-m+1else:
j +=1return-1
def get_next(self,needle):'''next数组
根据i-1推导i
次最长公共前后缀的前缀等于最长公共前缀的最长公共前后缀'''
m =len(needle)
j =-1
next_ =[-1]* m
next_[0]=-1for i in range(1,m-1):
j = next_[i-1]while j!=-1 and needle[j+1]!= needle[i]:#i-1最长公共前缀的最长公共前缀
j = next_[j]if needle[j+1]== needle[i]:
j +=1
# 相等后公共前后缀长度+1
next_[i]= j
return next_