代码随想录算法训练营第九天 | 28. 实现 strStr()(跳过)、459.重复的子字符串(跳过)、双指针法总结

28. 实现 strStr()

459.重复的子字符串

 听卡哥的准备跳过了KMP算法,等我修炼完60天后,最后第61天时再回来做这两题

双指针法总结章节

数组篇

移除元素

这题一般想到的都是利用for+erase函数来完成,但erase函数的时间复杂度也是O(n),因此时间复杂度是O(n^2),所以我们可以利用双指针法来完成,快指针相当于读指针,慢指针相当于写指针,当快指针读到需要的元素时,我们写入慢指针即可

一般移除操作都可以利用这个方法

字符串篇

反转字符串

这题我们利用双指针一头一尾进行交换即可,利用swap()函数,里面是两个在值 

替换数字

很多数组(字符串)填充类的问题,都可以先预先给数组扩容到填充后的大小resize(),然后在从后向前进行操作,一个指向扩容后的数组尾部,一个指向旧数组尾部,从后往前进行操作

为什么不从前往后?

因为从前往后操作时,我们每次操作都要移动后面所有的元素,因此时间复杂度是O(n^2),而从后往前只需要O(n)

翻转字符串里的单词

因为这里要求我们删除多余的空格,因此我们联想到数组篇的移除元素,我们只需要利用快指针填充单词时,当慢指针不是第一个单词时,遇到新单词自己补上一个空格即可,去除后记得resize一下,然后就比较简单了,先整体翻转,再逐个反转单词就行,后面的右旋转字符串也是如此

链表篇

反转链表

我们只需要利用双指针,定义一个pre指针,和cur指针,将cur指针的节点指向pre指针然后同时移动即可,这里注意cur指针的下一个节点是需要临时变量保存的,否则会丢失,切记不要空指针操作,还有虚拟头结点法要记住,统一了链表操作,最后记得delete

删除链表的倒数第N个节点 

这题我们只需要定义一个快慢指针,都从虚拟头节点出发, 且fast指针先移动n步,然后同时移动就可以找到倒数第N个了,但是如果要删除,那么fast需要走n+1,slow指向的则是删除节点的上一个节点,方便删除操作

链表相交

 这题注意的一个点是只有地址相同才是相同节点,那么也是利用双指针法操作,分别在两个链表处定义一个指针,然后记录两个链表的长度,使得长的那个为a链表,随后求出他们的len差,让长的a链表先走len差步,然后同时比较即可,找到地址相同的,那么就是相交的节点了

环形链表2

这题我们同样利用双指针法,快指针每次走两步,慢指针每次走一步,(切记要判断空指针),当有环时,这两指针必定会相遇,因为相对速度是1,随后在相遇位置和链表头同时出发一个指针,相遇时即是环口(数学公式推导出来的)

N数之和篇

两数之和/四数相加 

因为这两题都不需要去重,因此我们可以直接利用哈希map进行操作即可 

N数之和

但哈希map并不适用于N数之和要去重的操作,虽然利用双指针的时间复杂度一样,但将哈希map的结果放到vector中再去重会复杂很多,且剪枝有限

因此我们使用双指针法,三数之和就是先找a,剪枝操作就是a大于目标值且a是大于0了,那么就可以直接break了,同时去重操作就是只要nums[i] == nums[i-1] 就continue就可以了,遍历过的元素不需要再次遍历

随后我们利用双指针从一头一尾开始收缩,遍历剩下的元素,因为这里不需要顺序,因此我们sort后,利用三数和>target就让right指针左移缩小,<target就让left右移放大,找到结果后,先收获结果,再进行b,c元素去重,已经是结果的元素直接跳过即可,注意判断指针是否越界

四数之和就是在三数之和外面,再套一个for循环即可,扩展剪枝和去重操作就可以,记得剪枝是break最后一起return即可,N数之和以此类推

收获

今天的KMP算法没看,不知道啥是前缀,等我后面刷了一些难得算法后,再来回头看这两道题,剩下的就是复习操作,加油吧

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值