# leetcode 28 字符串匹配 O(N)复杂度解法

class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if needle == '': return 0

def judge(pos):
if haystack[pos:pos+len(needle)] == needle:
return 1
return 0

for idx, c in enumerate(haystack):
if needle[0] == c:
p1, p2 = int(len(needle)/2), (len(needle)-1)
if idx + p2 < len(haystack) and needle[p2] == haystack[idx+p2] and needle[p1] == haystack[idx+p1]:
result = judge(idx)
if result: return idx

return -1


“mississippi”
“issip”

    def strStr(self, haystack: str, needle: str) -> int:
if needle == '': return 0

p, pos = 0, 0
while p < len(haystack):
if haystack[p] == needle[pos]:
pos += 1
if pos == len(needle):
return p-pos+1
elif pos > 0:
p -= pos - 1
pos = 0
if haystack[p] == needle[pos]: pos += 1
p += 1

return -1


dp = KMP(pat)
match1 = search(txt1, pat, dp)
match2 = search(txt2, pat, dp)


import numpy as np
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if needle == '': return 0

# 字符转换为索引
def c2i(c):
return ord(c)-ord('a')

def i2c(i):
return chr(i+ord('a'))

# dp矩阵：当前位置+输入元素 -> 下一个位置
dp = np.zeros((len(needle), 26), dtype=int)

# dp数组填充
dp[0][c2i(needle[0])] = 1
X = 0
for j in range(1, len(needle)):
for i in range(26):
if i2c(i) == needle[j]:
# 若等于该字符，转换到下一个
dp[j][i] = j+1
else:
# 若不等，寻求上一个相等元素帮助
dp[j][i] = dp[X][i]
X = dp[X][c2i(needle[j])]

# 搜索
j = 0
for i in range(len(haystack)):
j = dp[j][c2i(haystack[i])]
if j == len(needle):
return i-len(needle)+1

return -1



class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if needle == '': return 0

# 构建dp数组（next数组）
dp = [-1 for _ in range(len(needle))]
k, j = -1, 0 # k = next[j], j = 1
while j < len(dp):
# 每次迭代, next[j] = k
if k < 0 or needle[j] == needle[k]:
k += 1
j += 1
if j == len(dp):
break
dp[j] = k
else:
k = dp[k]

# 搜索
i, j = 0, 0
while i < len(haystack):
if j < 0 or needle[j] == haystack[i]:
i += 1
j += 1
if j == len(needle):
return i-j
else:
j = dp[j]

return -1


09-29 853
12-04 143
07-07 745