题目大意:实现字符串匹配函数,即在文本串S中查找一个模式串P的出现位置,若不出现返回-1
题目分析:暴力解法,将模式串P与文本串S一位一位的比较,若相同,则继续比较下一位;若不同,则将模式串P向后移动一位,继续往后比较。时间复杂度为O(m*n),假设文本串S的长度为m,模式串P的长度为n。
代码展示:
class Solution(object):
def strStr(self, haystack, needle):
sLen = len(haystack)
pLen = len(needle)
i = 0
j = 0
while i<sLen and j<pLen:
if haystack[i]==needle[j]:
i += 1
j += 1
else:
i = i-j+1
j = 0
if j==pLen:
return i-j
else:
return -1
方法二:使用KMP算法,将时间复杂度降到O(m+n),KMP算法的主要思想是当出现字符串不匹配时,将模式串移动几位,而不是每次都向后移动一位。移动的位数 = 不匹配字符所在位置 - 不匹配字符对应的next值。
next数组的含义是:若next[j]=k,则表示j之前字符串中有最大长度为k的相同前缀、后缀。
举个例子,假设模式串为ABCDABD,则next数组表是这样的:
模式串 | A | B | C | D | A | B | D |
next数组 | -1 | 0 | 0 | 0 | 0 | 1 | 2 |
解释:令第一个字符A的next值为-1,第二个字符B前面的字符串为A,它的相同的前缀后缀为0。什么是相同的前缀后缀呢?比如说,ABCAB,这里AB就是相同的前缀后缀,长度为2。因为AB在字符串的前面后面都出现了。同理,再来观察模式串,最后一个字符D的next值为2,表示它前面的字符串ABCDAB有长度为2的相同的前缀后缀。
代码展示:
class Solution(object):
def strStr(self, haystack, needle):
sLen = len(haystack)
pLen = len(needle)
nextNum = self.getNext(needle)
i = 0
j = 0
while i<sLen and j<pLen:
if j==-1 or haystack[i]==needle[j]:
i += 1
j += 1
else:
j = nextNum[j]
if j==pLen:
return i-j
else:
return -1
def getNext(self,needle):
nextNum = []
pLen = len(needle)
nextNum.append(-1)
k = -1
j = 0
while j<pLen-1:
if k==-1 or needle[k]==needle[j]:
k += 1
j += 1
nextNum.append(k)
else:
k = nextNum[k]
return nextNum
关于KMP算法的主要思想,
点这里。