28. 找出字符串中第一个匹配项的下标(实现strStr())
使用库函数
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
return haystack.find(needle)
暴力解法
- 如果needle在haystack存在,起始点一定不会大于len(haystack) - len(needle) + 1
# Time complexity: O((M-N)*N)
# Space complexity: O(1)
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
for i in range(len(haystack) - len(needle) + 1):
if haystack[i] == needle[0]:
flag = True
for j in range(1, len(needle)):
if needle[j] != haystack[i+j]:
flag = False
break
if flag:
return i
return -1
KMP算法
-
构建最长公共前缀后缀list(LPS):
prevLPS同时是字符i的最长公共前缀后缀的数值
- 如果字符相等,
prevLPS +=1,lps[i] = prevLPS - 如果不等,
prevLPS回退到lps[prevLPS-1]的位置再进行比较,一直到字符相等或prevLPS = 0 - 更新
lps[i]=prevLPS,并向前移动i指针
- 如果字符相等,
-
比较haystack和needle,当字符不相等时,利用最长公共前缀后缀list来找到下一个需要比较的字符下标(更新
j = lps[j-1])
# Time complexity: O(M+N)
# Space complexity: O(N)
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
if needle == "":
return 0
# stands for longest preffix suffix, length always equals to len(needle)
lps = [0] * len(needle)
prevLPS = 0
for i in range(1, len(needle)):
while prevLPS > 0 and needle[i] != needle[prevLPS]:
prevLPS = lps[prevLPS-1]
if needle[i] == needle[prevLPS]:
prevLPS += 1
lps[i] = prevLPS
i, j = 0, 0
while i < len(haystack):
if haystack[i] == needle[j]:
i, j = i+1, j+1
else:
if j != 0:
j = lps[j-1]
else:
i += 1
if j == len(needle):
return i - len(needle)
return -1