代码随想录刷题第九天
实现 strStr() (LC 28) (很难,一刷不一定掌握)
实现 strStr()
函数。
给定一个 haystack
字符串和一个 needle
字符串,在 haystack
字符串中找出 needle
字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1
。
示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2
示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1
说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
本题是KMP 经典题目。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
代码实现:
class Solution(object):
def strStr(self, haystack, needle):
if len(needle) == 0:
return 0
next1 = self.getNext(needle)
print(next1)
j = 0
for i in range(len(haystack)):
while j>0 and haystack[i] != needle[j]:
j = next1[j-1]
if haystack[i] == needle[j]:
j+=1
if j == len(needle):
return i-len(needle)+1
return -1
def getNext(self, needle):
next1 = [0 for _ in range(len(needle))]
j = 0
next1[0] = 0
for i in range(1, len(needle)):
while j>0 and needle[i]!=needle[j]:
j = next1[j-1]
if needle[i] == needle[j]:
j+=1
next1[i] = j
return next1
重复的子字符串 (LC 459)
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例:
输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。
输入: “aba”
输出: False
输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)
移动匹配:
如果一个字符串S
是由一个子字符串组成的,则该两倍的该字符串S+S
前后相连,中间还能组成一个字符串S
.
代码实现:
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
n = len(s)
if n <= 1:
return False
ss = s[1:] + s[:-1]
print(ss.find(s))
return ss.find(s) != -1
KMP
一个字符串的最大公共前后缀, 如果前缀是从字符串第一个元素开始的,后缀是从字符串最后一个元素开始的,则前后缀没包含的元素则为重复子串,具体思路如下:
代码实现:
class Solution(object):
def repeatedSubstringPattern(self, s):
if len(s) == 0:
return False
nxt = self.getNext(s)
if nxt[-1]!=0 and len(s) % (len(s) - nxt[-1])==0:
return True
return False
def getNext(self, s):
nxt = [0]*len(s)
j = 0
nxt[0] = 0
for i in range(1, len(s)):
while (j>0 and s[i]!=s[j]):
j = nxt[j-1]
if s[i]==s[j]:
j+=1
nxt[i] = j
return nxt
总结:
今天主要学习了KMP算法,前缀表怎么构造。如果当前i=j,j+1; 如果i!=j, j=next[j-1]; next[i]=j
KMP很难,二刷还要持续复习!!!