代码随想录算法训练营第一天|数组理论基础,704. 二分查找,27. 移除元素
代码随想录算法训练营第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
代码随想录算法训练营第三天|链表理论基础,203.移除链表元素,707.设计链表,206.反转链表
代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II,总结
代码随想录算法训练营第五天|哈希表理论基础,242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和
代码随想录算法训练营第六天|454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和,总结
代码随想录算法训练营第七天|344.反转字符串,541. 反转字符串II,卡码网:54.替换数字,151.翻转字符串里的单词,卡码网:55.右旋转字符串
题目链接: 28.实现strStr()
**题目内容:**给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
视频讲解:帮你把KMP算法学个通透!(理论篇);帮你把KMP算法学个通透!(求next数组代码篇)
核心思想:KMP算法
class Solution:
def getNext(self,next:List[int],s:str) -> None:
#初始化next数组
next[0]=0
j=0
#(j是前缀末尾,i是后缀末尾)
for i in range(1,len(s)):
#处理不同情况的前后缀
while j>0 and s[i]!=s[j]:
j=next[j-1]
#处理相同情况的前后缀
if s[i]==s[j]:
j+=1
#更新next数组
next[i]=j
def strStr(self, haystack: str, needle: str) -> int:
#needle字符串的长度为0的情况
if len(needle) == 0:
return 0
#初始化next数组
next=[0]*len(needle)
#生成next数组
self.getNext(next,needle)
j=0
#遍历haystack字符串
for i in range(len(haystack)):
#匹配不上时,回撤
while j>0 and haystack[i]!=needle[j]:
j=next[j-1]
#匹配上时,继续向前匹配
if haystack[i]==needle[j]:
j+=1
#匹配完成,输出下标
if j==len(needle):
return i-len(needle)+1
return -1
题目链接: 459.重复的子字符串
**题目内容:**给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
视频讲解:字符串这么玩,可有点难度! | LeetCode:459.重复的子字符串
移动匹配法:
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:
def repeatedSubstringPattern(self, s: str) -> bool:
if len(s)==0:
return False
next=[0]*len(s)
self.getNext(next,s)
if next[-1]!=0 and len(s)%(len(s)-next[-1])==0:
return True
return False
def getNext(self,next,s):
#初始化next数组
next[0]=0
j=0
for i in range(1,len(s)):
#处理不同前后缀的情况
while j>0 and s[i] != s[j]:
j=next[j-1]
#处理相同前后缀的情况
if s[i]==s[j]:
j+=1
#更新next数组
next[i]=j
return next
双指针法效率的优势:通过两个指针在一个for循环下完成两个for循环的工作。
在原地移除数组上的元素时,数组上的元素不能真正的删除,只能覆盖,因此可以采用双指针法。