相信大家已经对双指针法很熟悉了,但是双指针法并不隶属于某一种数据结构,我们在讲解数组,链表,字符串都用到了双指针法,所有有必要针对双指针法做一个总结。

数组篇

在数组:就移除个元素很难么?中,原地移除数组上的元素,我们说到了数组上的元素,不能真正的删除,只能覆盖。

一些同学可能会写出如下代码(伪代码):

for (int i = 0; i < array.size(); i++) {if (array[i] == target) {array.erase(i);}
}

这个代码看上去好像是O(n)的时间复杂度,其实是O(n^2)的时间复杂度,因为erase操作也是O(n)的操作。

所以此时使用双指针法才展现出效率的优势:「通过两个指针在一个for循环下完成两个for循环的工作。」

字符串篇

在字符串:这道题目,使用库函数一行代码搞定中讲解了反转字符串,注意这里强调要原地反转,要不然就失去了题目的意义。

使用双指针法,「定义两个指针(也可以说是索引下表),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。」,时间复杂度是O(n)。

在替换空格 中介绍使用双指针填充字符串的方法,如果想把这道题目做到极致,就不要只用额外的辅助空间了!

思路就是「首先扩充数组到每个空格替换成"%20"之后的大小。然后双指针从后向前替换空格。」

有同学问了,为什么要从后向前填充,从前向后填充不行么?

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。

「其实很多数组(字符串)填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。」

那么在字符串:花式反转还不够!中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要产出冗余空格。

「在删除冗余空格的过程中,如果不注意代码效率,很容易写成了O(n^2)的时间复杂度。其实使用双指针法O(n)就可以搞定。」

「主要还是大家用erase用的比较随意,一定要注意for循环下用erase的情况,一般可以用双指针写效率更高!」

链表篇

翻转链表是现场面试,白纸写代码的好题,考察了候选者对链表以及指针的熟悉程度,而且代码也不长,适合在白纸上写。

在链表:听说过两天反转链表又写不出来了?中,讲如何使用双指针法来翻转链表,「只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。」

思路还是很简单的,代码也不长,但是想在白纸上一次性写出bugfree的代码,并不是容易的事情。

在链表中求环,应该是双指针在链表里最经典的应用,在链表:环找到了,那入口呢?中讲解了如何通过双指针判断是否有环,而且还要找到环的入口。

「使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。」

那么找到环的入口,其实需要点简单的数学推理,我在文章中把找环的入口清清楚楚的推理的一遍,如果对找环入口不够清楚的同学建议自己看一看链表:环找到了,那入口呢?。

N数之和篇

在哈希表:解决了两数之和,那么能解决三数之和么?中,讲到使用哈希法可以解决1.两数之和的问题

其实使用双指针也可以解决1.两数之和的问题,只不过1.两数之和求的是两个元素的下标,没法用双指针,如果改成求具体两个元素的数值就可以了,大家可以尝试用双指针做一个leetcode上两数之和的题目,就可以体会到我说的意思了。

使用了哈希法解决了两数之和,但是哈希法并不使用于三数之和!

使用哈希法的过程中要把符合条件的三元组放进vector中,然后在去去重,这样是非常费时的,很容易超时,也是三数之和通过率如此之低的根源所在。

去重的过程不好处理,有很多小细节,如果在面试中很难想到位。

时间复杂度可以做到O(n^2),但还是比较费时的,因为不好做剪枝操作。

所以这道题目使用双指针法才是最为合适的,用双指针做这道题目才能就能真正体会到,「通过前后两个指针不算向中间逼近,在一个for循环下完成两个for循环的工作。」

只用双指针法时间复杂度为O(n^2),但比哈希法的O(n^2)效率高得多,哈希法在使用两层for循环的时候,能做的剪枝操作很有限。

在双指针法:一样的道理,能解决四数之和中,讲到了四数之和,其实思路是一样的,「在三数之和的基础上再套一层for循环,依然是使用双指针法。」

对于三数之和使用双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。

同样的道理,五数之和,n数之和都是在这个基础上累加。

总结

本文中一共介绍了leetcode上九道使用双指针解决问题的经典题目,除了链表一些题目一定要使用双指针,其他题目都是使用双指针来提高效率,一般是将O(n^2)的时间复杂度,降为O(n)。

建议大家可以把文中涉及到的题目在好好做一做,琢磨琢磨,基本对双指针法就不在话下了。

本文:https://github.com/youngyangyang04/leetcode-master​已经收录,里面还有leetcode刷题攻略、各个类型经典题目刷题顺序、思维导图,可以fork到自己仓库,有空看一看一定会有所收获,如果对你有帮助也给一个star支持一下吧!

我的B站(里面有我讲解的算法视频以及编程相关知识):https://space.bilibili.com/525438321

我是程序员Carl,哈工大师兄,先后在腾讯和百度从事技术研发多年,利用工作之余重刷leetcode,更多      精彩算法文章尽在:      代码随想录,关注后,回复「Java」「C++」「python」「简历模板」等等,有我整理多年的学习资料,可以加我      微信,备注「个人简介」+「组队刷题」,拉你进入刷题群(无任何广告,纯个人分享),每天一道经典题目分析,我选的每一道题目都不是孤立的,而是由浅入深一脉相承的,如果跟住节奏每篇连续着看,定会融会贯通。

看完这一篇,在leetcode上双指针法题目你随便做!相关推荐

  1. 别在问PMP和ACP哪个更有用了,看完这一篇你就知道!

    别在问PMP和ACP哪个更有用了,看完这一篇你就知道. 老原很多粉丝和学员在我的后台问我: 要不要考PMP和ACP? PMP和ACP的区别是啥? PMP.ACP证书考哪个更有用?还是两个都考? PMP ...

  2. 分享一波关于做Kaggle比赛,Jdata,天池的经验,看完我这篇就够了。

    @Author : Jasperyang @School : BUPT 这篇文章同时在知乎里放着- 写在前面 Kaggle的数据挖掘比赛近年来很火,以至于中国兴起了很多很多类似的比赛,做了两个这种类型 ...

  3. 计算机进制转换(看完这一篇你就全懂了)—基础篇

    我相信很多人都学过进制的转换,但是总是转不过来,你只需要看完这一篇,你对进制的理解与转换一定会很熟练. 众所周知计算机只能识别0和1,其他的文字.数字.字符只能通过转换成进制,然后让计算机识别,并显示 ...

  4. python--半自动爬取Leetcode上面的所有题目并转成word打印

    python–半自动爬取Leetcode上面的所有题目并转成word打印 python–半自动爬取Leetcode上面的所有题目并转成word打印 写在前面 代码逻辑 代码结构: 代码流程 具体代码 ...

  5. 网络安全工程师入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

    前言 想要成为网络安全工程师,却苦于没有方向,不知道从何学起的话,下面这篇 网络安全入门 教程可以帮你实现自己的网络安全工程师梦想,如果想学,可以继续看下去,文章有点长,希望你可以耐心看到最后! 1. ...

  6. 网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇就够了!

    想要成为黑客/红客,却苦于没有方向,不知道从何学起,下面这篇网络安全入门教程可以帮你实现自己的黑客梦想,如果想学,可以继续看下去,文章有点长,希望你可以耐心看到最后 网络安全入门路线 Web安全相关概 ...

  7. Android Studio Lint 工具看完这一篇还不够

    前言 以前对下面的问题,我的态度是,不报错就是没问题,报错就用快捷键,根据Android Studio提示修复问题,从来不去问个为什么?现在代码洁癖症越来越严重的我,忍不住想看清什么东西在搞鬼. 认真 ...

  8. 程序员入门教程【非常详细】从零基础入门到精通,看完这一篇就够了 !

    零基础编程入门先学什么?编程语言有几百种,我们应该怎么选择.想学习编程,加入互联网行业,哪一个更有前途?在小白学习编程会有各种各样的问题,今天小编我就来为你解答. 一.怎么选择编程语言 编程语言有很多 ...

  9. 看完这一篇你还不会JavaWeb吗

    JavaWeb 引言 相信小伙伴们大学实训的时候,会有过javaweb实训吧,反正我们那是,在没学习各大框架之前,我们都是学习javaweb的原生操作,相信原生基础好了,后面框架无非是提供便利,所以这 ...

  10. 当下最火的中台到底是个什么鬼,看完这一篇最通俗易懂的文章后,你就会彻底明白了!...

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你提升技术视野! 背景 自从阿里巴巴现任CEO逍遥子在2015年提出"大中台,小前台"战略以来,关于"什么是 ...

最新文章

  1. Redis集群——利用Gearman在Lnmp架构中做MySQL的缓存服务器
  2. Linux学习(四)---用户管理
  3. RHCE实验:Linux下基于xinetd的访问控制
  4. 聊一聊:你觉得这个新Logo值200万吗?
  5. HDU 1568 Fibonacci
  6. pytest结合allure-pytest插件生成allure测试报告
  7. java关键字transient和volatile的基本含义和使用方法
  8. Python编码风格
  9. 五分钟了解DOM 事件模型
  10. c++——const关键字
  11. 文本识别CRNN模型介绍以及pytorch代码实现
  12. 【接口测试】接口测试用例设计
  13. 【校招VIP 前端】电影详情模块的开发文档设计实战
  14. windows系统升级
  15. 黑冰客防骗子—常见网络骗子骗术防御要点
  16. 不限专业和工作年限就能报考的证书有哪些?
  17. Maven settings.xml 文件详解
  18. rm -rf 命令 与正则表达式
  19. ECharts提示框数字保留两位小数
  20. 如何查询本机的内网IP地址

热门文章

  1. Vue 项目优化,持续更新...
  2. linux 下tomcat catalina.out日志操作
  3. wire routing 网格寻址
  4. 【CSharp】C#中equals与==小记
  5. Winform 分页用户自定义控件( ML.Pager.WinControl)
  6. python机器学习_(1)鸢尾花的分类
  7. angularJS使用rootscope创建父域和子模态框通用的属性与函数
  8. 士兵杀敌 三 --- O( 1 ) 的时间复杂度 .
  9. 变量作用域、声明提前、作用域链
  10. Base64与MIME和UTF-7