如何使用「番茄法」高效的写算法题?


戳蓝字“CSDN云计算”关注我们哦!  

640?wx_fmt=jpeg

作者:侯振宇

转自五分钟学算法


01 目的 




持续做算法题的目的仍然是自身能力提升。可以继续细化成三点:


  • 保持思维敏捷。非常重要,状态好才能保持对编程的热情。

  • 对基础的数据结构、查找和排序保持熟练。能解决日常开发中的性能相关问题。

  • 积累对问题域的探索。只有对问题域有足够的探索,才可能举一反三,迸发灵感。




02 方法 




为了更有效地实现上面的目标。推荐用下面的方式来做题:


严格使用番茄时钟进行规划


在刷题的过程中非常最容易产生挫败感,无法坚持。原因是,长时间的思考导致疲倦,多次积累的疲倦使得自己产生了 抵触记忆。以至于会下意识觉得做题就是 刻苦。


推荐大家在开始之前看看《意志力》。里面指出 喜好 是会被记忆操控的,如果每次做一件事最后留下的映像都是轻松愉快的,那么人就会越来越喜欢做此事,反之厌恶。所以为了能保持做题的兴趣,务必每次要主动给自己留下好的记忆。


番茄时钟能够很好地保障不会出现 长时间 的思考,同时也能保障不容易 疲倦。如果你已经能很熟练的使用番茄时钟,请跳过。如果你对番茄时钟的印象仍然只是20分钟休息一次。那么请继续阅读。


番茄时钟有两个重点,一是通过长期的训练,让大脑习惯在一段时间内保持高效。二是通过要求每次在开始前有规划和每次结束后有总结,保障产出。当把这两点应用到做算法的过程中时,应该采取以下的方式:


用一个番茄时钟对题目进行彻底的分析


目前 LeetCode 上的题大致可分为两种类型:


  • 对某种复杂规则的彻底解析,很有可能要构造状态机,充分考虑边界情况。

  • 对某种数据结构及算法的应用。

  • 对数学概念、遍历、动态规划等的综合应用。


在这个分析过程中首先要大致判断出属于哪一类。


在掌握了基本的数据结构和算法后,应该能很好的判断是不是属于前两类。


如果判断不出说明需要回头先重新复习基本数据结构。


推荐《算法》一书。


不要强行刷题。算法书的每种数据结构及算法的大概思路、解决的问题以及相应的时间和空间复杂度了解之后可以再回来。


第一种情况


例子:LeetCode 第 65 号问题 --- 有效数字


这个番茄时钟内的目标是:


  • 理清题目背后解法要用的技术

  • 充分收集可能涉及到的边界


完成后应该有的总结是:


  • 是否理清了要用的技术

  • 是否有不确定的地方

  • 收集到的边界是否能覆盖所有情况


如果发现在要用的技术中有不熟悉的地方,应该立即中断,开启另一个番茄时钟进行学习。切忌盲目尝试。


当发现有不确定的地方时,重新开启一个番茄时钟,按照当前思路把不确定地方当成一个单独的算法问题进行解决。


第二种情况


例子: LeetCode 第 493 号问题 --- 翻转对


这一类题目通常采取遍历的方法一定都能找到解法。重点是找到最优解,因此需要提前有足够的数据结构的知识。


数据结构可大致分为链(数组、栈、队列)、树、图。在这三类数据中要分别掌握排序和查找算法。特别是相应的时间复杂度。


这类题目很好判断,通常题目中会描述了几个数据或者状态的关联的关系,然后需要你找出符合条件的某些数据。那么将题目中的关联关系转换成相应的数据结构,再使用对应算法就够了。要对数据结构的足够熟悉,才能知道如何转化。


这种情况下番茄时钟的目标是:


  • 将问题转化为对相应数据结构的问题。


总结是:


  • 需不需要分情况讨论,需要一种数据结构还是多种

  • 相应数据结构是否能完全覆盖题目问题中的所有情况


第三种情况


例子:LeetCode 第 76 号问题 --- 最小覆盖子串


这一类情况最好用排除法,发现不是第一种或者第二种,那么再往这种情况下考虑。这类题的特点是通常是发散性质,刚看到题目容易有思路,但不太容易找到最优解。这种情况下,也要先判断题目子类型。


  • 如果发现题目能从遍历的角度解决问题,那么可以往遍历的优化上去想。例如是否在遍历的时候能够排除掉一些情况。或者通过排序等手段之后,能实现遍历时排除某些情况。

  • 如果发现题目中存在多种约束关系,然后求某个值,那么可以往数学方程组上去想。

  • 如果发现问题可以被递归解决,并且能够将递归方式转化成顺序方式,可以往动态规划上去想。


在这种情况下,番茄时钟的目标:


  • 判断出题目类型。


总结:


  • 是否有其他类型更适合。

  • 是否需要多种手段结合。


执行时的番茄时钟


当分析完之后,建议不要开始写代码,一定要休息片刻。执行阶段是对我们平时写代码状态的一种锻炼,应该非常珍惜。如果一个番茄时钟执行不完,应该拆分成多个。在这段时间中,设定的番茄时钟目标应该是:


  • 高效地验证分析阶段的思路


要实现执行高效,最重要的是养成良好的编码习惯,不要犯小错误。要始终朝着只要想清楚了,一次写好,不要调试的状态要求自己。这里常见的小错误有:


  • 拼写错误。变量命名要足够清楚,不要用单个字母或者语意不明的单词。

  • 数组边界未考虑。

  • 空值未考虑。

  • 用 Math.ceil 之类函数时未考虑清楚上下界。


调试超过写代码时间 30% 时说明状态非常有问题。在这个阶段的总结是:


  • 是否完成了对分析的验证

  • 编码过程是否足够高效


如果中间发现了分析阶段的错误或者疏漏,应该立即结束编码,休息。并且重新开启分析阶段的时钟。


切忌边写边改方案。


如果发现编码过程状态不够好,应该加长休息时间,或者干脆结束掉。不要给自己留下低效的映像。


将任务留到第二天其实也可以检验自己第一天的思路是否足够系统化,如果是,那么第二天应该能很快的重新找回思路。


任一番茄时钟结束时


一定要做好总结,特别是当没有解出题来,没有思路的时候,一定要通过结束阶段的总结来反思犯了什么错误。解出来了也一定要总结题目的特点,题目中哪些要素是解出该题的关键。不做总结的话,花掉的时间所得到的收获通常只有 50% 左右。


在题目完成后,要特别注意总结此题最后是归纳到哪种类型中,它在这种类型中的独特之处是什么。经过总结,这样题目才会变成你在此问题域中的积累。


做好总结,让每道题都有最大的收获。一个月之后自己的状态应该会有很大变化。



03 如何分享 




在这个仓库中进行解题分享时,建议大家就把自己番茄时钟的执行记录进行分享。最后标准的解法以及思路其实在 discussion 中都有。对他人有用的分享不是结果,而是:


  • 你在番茄时钟中是如何规划的,也就是番茄时钟的目标。

  • 你是如何分析,也就是思路。

  • 你的结论是什么,或者是你在执行时除了什么问题。

  • 你所总结出的题目的关键部分。也就是对问题域进行探索的经验。


640?wx_fmt=png


5 月 26 日- 5 月 27 日,第一届 CTA 核心技术及应用峰会将空降杭州国际博览中心。
目前双日会议预售票发售最后
 天,仅售 799 元(原票价1099元)。点击阅读原文,立享预售优惠。
了解大会详情,请添加票务小助手微信:15101014297,备注「CTA」。

640?wx_fmt=jpeg


福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


640?wx_fmt=jpeg


推荐阅读:

  • 腾讯面试:一条SQL语句执行得很慢的原因有哪些?

  • 程序员专属小情话,哎呦,不错哦!| 程序员有话说

  • 普通家庭走出信息学才子,抱病参赛夺世界信奥亚军 | 人物志

  • Rust今天4岁啦, 为什么越来越多的知名项目用Rust来开发?

  • 商汤“变法”:推中小学AI教材,mini自驾车,要打造AI时代的「清明上河图」

  • 转行AI成为技术大牛,你需要理解这两项技术!


640?wx_fmt=png真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/523756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双因子认证(Two-factor authentication)

一、简介 简言之,双因素身份验证(也称为“两步验证”)是指身份验证涉及两个阶段——通常是除了常规密码)之外的某种一次性密码(OTP:One-Time Password)。网上银行已经使用这种方法很长一段时间了…

Spring中,使用工具类无法自动注入service

这个问题我其实遇到很久了,目前解决方案是手动注入service,并且把工具类也手动注入。 场景: 在spring中,我们经常会定义工具类来做一些奇怪的事情,我当前是通过定时任务quarz调度工具类,工具类再调servic…

sizeof与strlen使用中的问题

概述 直接上代码,使用中经常会涉及到sizeof与strlen计算的问题,下面看例子: char *pstr "hello"; char pstr[] "hellonini"; char pstr[6] "hello";上述求sizeof(pstr)的值,分别为&#xff1a…

从人工智能到云,英特尔开源技术推动软件栈创新

戳蓝字“CSDN云计算”关注我们哦!2019年英特尔开源技术峰会(OSTS) 【CSDN记者现场报道】5月14-16日,英特尔主办一年一度的开源技术峰会(OSTS)。该峰会源自2004年的一次内部会议,从最初只有几十个…

Axis2搭建WebService服务

使用Axis2搭建WebService服务 文章目录一、服务端部署1.1 在web.xml配置文件中添加映射路径:2. 创建目录及文件3. 新建服务接口4. 新建接口实现类5. 发布服务6. 浏览器测试二、客户端部署2.1 Axis2客户端通用工具类封装(企业版本)2.2 单元测试(命名空间默认)&#x…

c++实现引用计数

概述 当有指针指向同一块内存空间时,计数器加1,没增加一个指向该内存空间的指针,计数器加1,同理,当原本指向该内存空间的指针指向另一块内存,计数器减1,被指向的另一个内存的计数器加1。下面是…

焦虑的 BAT、不安的编程语言,揭秘程序员技术圈生存现状!

戳蓝字“CSDN云计算”关注我们哦!【CSDN 编者按】在迭代不休的技术圈中,仅在过去的一个月期间,我们见证了有史以来第一张黑洞照片的诞生;经历了为让人义愤填膺的 996;思考了作为程序员的年龄之槛;膜拜了技术…

axis2手动设置命名空间targetNamespace

修改services.xml&#xff1a; name &#xff1a;你暴露的接口服务名 targetNamespace 命名空间 <service name"ws" targetNamespace"url" >,添加targetNamespace属性&#xff0c;然后添加标签&#xff1a; <schema schemaNamespace"url&…

5G精华问答 | 除了速度,5G还能带来什么?

从2016年以来&#xff0c;5G热度逐步攀升。作为下一代移动通信网络&#xff0c;如果用一个关键词来形容5G&#xff0c;那就是“快”。5G不仅会极大地改变人们现有的生活和工作方式&#xff0c;提升通信效率&#xff0c;还可以加大很多前沿技术和产品落地的可能性。今天&#xf…

Spring获取JavaBean的xml形式和注解形式

Spring获取JavaBean的xml形式和注解形式 文章目录一、用xml文件方式管理JavaBean1. 创建一个xml配置文件2. 将一个Bean交由spring创建并管理3. 获取Spring上下文&#xff0c;获取bean二、用注解获取Javabean1. 创建一个class配置java文件2. 将一个bean交由Spring创建并管理3. 获…

C++中两个栈实现一个队列

引言 首先看这个标题的时候&#xff0c;需要联想到栈和队列的特点&#xff0c;栈是先进后出&#xff0c;队列是先进先出。假如三个元素1&#xff0c;2&#xff0c;3&#xff0c;将这三个元素依次入栈1后&#xff0c;再将栈1中元素依次出栈放入到栈2中&#xff0c;栈1中只留下最…

Kube-OVN:基于OVN的开源Kubernetes网络实践

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;今天&#xff0c;许多企业开始运行Kubernetes集群&#xff0c;并从中受益。但我们仍然…

IntelliJ IDEA中创建xml文件

1、file—setting&#xff0c;左上角输入template&#xff0c;2、在左侧栏找到File And Code Templates3、中间选中Files4、点击号&#xff0c;添加模板5、输入模板名字&#xff1a;Name:mybatis-cfg.xml &#xff08;name可以自定义&#xff09;6、后缀名extension&#xff1a…

C++冒泡排序

引言 冒泡排序作为排序中一个比较重要的方法&#xff0c;这里做一些简单的记录。 示例 本例中将一组数据2&#xff0c;4&#xff0c;3&#xff0c;8&#xff0c;5按照从小到大的顺序进行冒泡排序。首先说一下&#xff0c;冒泡排序是怎么排序的&#xff1a;将数组中相邻的两个…

Spring概念理解

什么是IOC&#xff1f; 控制反转&#xff0c;依赖注入 1、控制什么&#xff1f; 控制对象的创建及销毁(生命周期) 2、反转什么&#xff1f; 讲对象的控制权交给IOC容器

阿里云技术专家入选Apache Member;百度Q1财报:营收241亿元;华为面向全球发布AI-Native数据库……...

戳蓝字“CSDN云计算”关注我们哦&#xff01;嗨&#xff0c;大家好&#xff0c;重磅君带来的【云重磅】特别栏目&#xff0c;如期而至&#xff0c;每周二第一时间为大家带来重磅新闻。把握技术风向标&#xff0c;了解行业应用与实践&#xff0c;就交给我重磅君吧&#xff01;重…

c++选择排序

引言 选择排序就是找出每趟中的最小值或者最大值与对应趟数位置上的数值进行交换&#xff0c;从而排序&#xff0c;具体像序列&#xff1a;2&#xff0c;5&#xff0c;4&#xff0c;3&#xff0c;8若按照从小到大的顺序选择排序&#xff0c;总共5个元素&#xff0c;需要进行5-…

Java高级特性——反射

定义 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 1. 反射机…

C++快速排序(二)

引言 此文继上一次的c快速排序之后&#xff0c;是时隔一年后的重新领悟。快速排序就是从一列序列中选择一个数作为基数&#xff0c;一般以左边第一个元素为基数&#xff0c;然后定义两个变量left与right,left指向左边第一个元素&#xff0c;与基数指向相同&#xff0c;right指…

如何看待“英特尔是一家软件公司”?

戳蓝字“CSDN云计算”关注我们哦&#xff01;1968年7月&#xff0c;传奇半导体公司仙童的两位共同创办人罗伯特诺伊斯、高登摩尔从仙童请辞&#xff0c;共同创办了以“INTegrated ELectronics&#xff08;集成电子&#xff09;”前缀为名的一家电子公司&#xff0c;这家公司就是…