华山西峰顶
上周在公司分享了自己练习算法的心得和经验,有小伙伴表示分享的内容给他带来了价值,也很具备参考意义,于是就算法写成文章分享出来,近几个月来,自己每周都会花1、2小时在 Leetcode 上面练习算法,短短几个月下来也陆陆续续交出 40~50 的解题作业,算是一个小小的里程碑吧,以下是我最近的刷题记录:
所有的解题记录我传到了的公开的 Github 项目,有兴趣的可以访问链接看看
偶尔在算法群里也有小伙伴总是在问:“刷题太难了,自己总是虎头蛇尾,你们是怎么坚持下来的 ?,有什么方法吗?”,其实很多人刚开始都是热情满满,然后马上就三分钟热度了,这其实也很正常,我也通过自己几个月的探索和坚持,踩了不少坑,所以总结了不少我个人觉得行之有效的刷题经验,跟大家分享一下,也避免大家后续再走弯路
总体大纲如下:(预计 5分钟能读完)
相信高手都明白算法和数据结构是基本功,但是还有很多刚入行的新人不是很明白,我的个人观点如下:
常用的编程语言大多都是对数据结构的封装,所以很多面试官特别喜欢问以下的问题,例如:
而且根据我了解的很多面试官其实根本不在乎你使用什么编程语言,熟练使用什么技术框架,这些只是“术”的层面,他们更加在乎你是否具备解决问题和抽象问题的能力,这些才更加具备长期的价值,更加接近“道”的层面,那么如何考察呢 ?就是通过算法,最好是通过在白板上给出解题的过程和思路,例如 Google 就特别喜欢这样做。闲话扯的有点远,我们下面进入正题
我觉得既然下定决定要去学习,那么首先要调整的就是心态,这个社会大部分人都很浮躁,想要速成,但是学习是不可能速成的,需要先定好目标,然后一步一步向前行,首先我先推荐一本书《异类》:
这本书通过各种案例向大家传递了关于“一万小时“的理论,而且不是勤勤恳恳的重复的一万小时,必须是有目标,有阶段,不断按曲线成长的”一万小时“,不然的话你也只是在感动自己而已,任何不经思考的学习和练习都是徒劳
如果要按照这个理论,就是说一个普通人,每天要花 3-4 小时的学习成长,差不多持续十年,你才有可能成为行业的高手和专家,所以要明白很多成功都不是偶然的,很多看似轻松达成某些成就的人,背后都付出常人无法理解的痛苦和努力,就像那些看上去身材很好的人,他们显得很年轻,穿衣服也很好看,但是你没有看到他们咬紧牙关在锻炼的时间,bob 大叔在《程序员的职业素养》一书中也说过一句话”任何专业人士都需要保持刻意连续,钢琴家,医生,律师,拳击手,吉他手,乐队等等,想要成为专业人士都必须保持刻意的练习“,所以大家应该明白学习没有捷径,想要成为专业人士,就要付出相应的努力
学习和看书那么苦,那么累,还要坚持那么久,我们能不能想一些方法来减轻这种痛苦的感受?
答案是有的,也是我自己认为行之有效的一种,那么就是:用玩游戏的心态来学习(关于游戏如何利用反馈机制让人上瘾的细节我就不详细说明了,不了解的同学有兴趣自行去 Google 了解反馈机制对大脑的刺激)
那么具体如何操作呢 ?我简单总结以下两点:
回想一下你是如何成为 英雄联盟/王者荣耀 高手的 ?
主要分以下几步:
以上是玩游戏的步骤,那么对于练习算法,我们也可以用同样的步骤:
以上可以发现其实玩游戏的思路可以用在算法练习上,而且效果还不错,不过仅仅做到以上几点,还不能成为一个游戏高手,通常如果你想在游戏里面成为高手还需要做到如下几点,,我称之为:
Feedback 持续反馈:
如果能用以上的方法,再加上持之以恒的心态,应该就能成为一个(游戏/算法)的高手了
上面总结了如何调整心态,下面我们讲讲在刷题阶段的几点注意事项
我自己刚开始也是没有方法,上来就是一顿猛刷,结果刷了忘,忘了继续刷,结果浪费时间不说,而且自己也没有从中收获到价值,这对于出题的作者和我本人都是双输的结果,而且后面跟几个小伙伴在微信群里面组队刷题的时候,看到很多小伙伴都重复犯了这个错误,甚至有的人从此对算法失去兴趣,可惜可惜……
对于初学者练习算法,我有以下几点建议,简称 CPCT 法:
有一个很经典的算法问题,就是要计算 1+2+3+4....+100 的总和的方法:
因为 100 也不算很大,很多同学估计这样计算:
勉强计算 100 次后,我们得到 5050 的最终结果,
我们再把问题扩大一下,如果要计算的值不是 100, 而是 1 + 2 + 3 + 4 .... 一直到 1000, 或者 10000 呢 ?如果值是 1000,那么就要重复计算 1000 次,如果值是 10000 ,那么就要重复计算 10000 次,负责计算的人估计会崩溃了(没错,计算机也是这么想的),随着 N 越大,要计算的次数越多,这种需要计算 N 次的算法,我们评估它的时间复杂度为:O(n)
这时候还在读小学,并且不愿意透露姓名的高斯同学,发现的计算的规律,并且总结的求和公式:Y = n * (n + 1) / 2
使用这个公式不管要计算的值有多大,得到的结果都是相同,而且永远只需要计算一次,这种方法我们评估它的时间复杂度为:O(1)
这也是算法的目的:在保证结果正确的同时,将时间复杂度和空间复杂度降到最低
常见的大O表示法和常见的术语:
从优 >> 差的复杂度排序: