开篇词

labuladong 的算法小抄

GitHub

建议直接收藏首页地址(https://labuladong.gitbook.io/algo )到浏览器首页,而不要收藏某篇文章的地址,因为文章的地址和目录结构有关,如果目录结构改变,会导致你收藏文章的 url 出现 404。

本网站目前可以手把手带你解决 150 道 LeetCode 算法问题,而且在不断更新,全部基于 LeetCode 的题目,涵盖了所有题型和技巧。我已经把在每篇文章的开头加上了该文章可以解决的 LeetCode 题目链接,可以看完文章立即去拿下对应题目

本套教程即将出版,公众号「labuladong」后台回复关键词「电子书」,限时免费下载这份算法小抄的 PDF 版本。

关于学算法的个人方法论

大家好,我是 labuladong,我一直不知道我在大家心里是什么形象,不过我给我的公众号的定位是一个工具人的角色。

这一点应该可以感觉得出来,我们公众号的文章一直都是算法相关的文章,从来没有水文,没有生活的分享,没有任何情绪,这就是标准的工具人嘛。我的目的就是让大家来这里有所收获,高效搞定算法笔试,找到满意的工作,拿到不错的薪资,最后随口推荐下我的公众号就行了。

为什么我的定位是一个工具人呢?因为我这个人不太会聊天的。

你看我写的算法套路很通俗易懂,大家喜欢看,那只能代表我这个人的逻辑性很强,并不代表我来聊天大家就喜欢看,学习的时候才需要逻辑,平时又不需要。

不过,今天还是想简单和大家聊聊,因为很多读者问起,想让我讲讲怎么刷题,怎么学好算法,有没有必要去拿个算法竞赛奖之类的。

常规的回答呢,就是推荐一个书单,然后写一写自己的刷题经历,推荐大家多打比赛,多做项目,这是比较容易写的,而且阅读效果也会不错。

但本文就不这么搞,因为咱们都一样,特别喜欢买书,喜欢书籍的厚重感和充满科技感的封面,但真要翻开读上几页,恐怕就要打开咸鱼回血了。

关于刷题经验,其实一直在聊。我们号关于算法的各种套路,各种题型都已经分析地够多了,每篇文章开头都贴心地给你把对应的题目列出来了,有心的读者去按着历史文章认真学两周,应对常规的算法笔试真的就够了。

本文借着如何学习算法这个话题,分享下我的一些思维方式,希望能给大家一些启发。

学算法也好,学技术也好,我觉得做任何事情,一定要明白自己的目标是什么

这句话有两个关键词,第一个关键词是「目标」,可以量化的才叫目标。

你想变有钱,想学好算法,这就叫无法量化的目标,有多少钱才算有钱,学到什么程度才算学好?量化的一个最大的特点是可以拆分。

比如说目标是进大厂,计划半年内刷 300 道题,那这可以反向拆分,每个月刷 50 道,工作日每天刷两道,休息日每天刷一道,再细化,每天几点到几点固定为刷题时间,期间屏蔽所有应用通知,专心做题思考;然后每天反省刷题计划是否达标,如果没达标,是为什么,怎么弥补。

这就是计算机的递归思维,自顶向下,逐步求精,反向求解。我们旧文写了很多动态规划相关的题目,基本都是先写自顶向下的递归解法,然后改写成自底向上的迭代解法,因为递归思路清晰嘛。

自顶向下的思维显得有条理,清楚地知道自己下一分钟要干什么,自底向上的思维就有些眉毛胡子一把抓的感觉,你说谁对时间的利用效率高呢?

如果把这种根据目标来反向拆分的方法用到生活学习中,你就像个算法一样精确地按照既定的逻辑向目标逼近,攻城拔寨,好似人群中混进了个 AlphaGo,还愁达不到自己的目的?

第二个关键词是「明白」,不是说今天热血沸腾给自己制定计划,结果做着做着就被带偏了,真的明白应该是你每时每刻,每分每秒都明白目标是什么。

我指的被带偏不是说学着学着跑去刷抖音了,这种问题可以通过物理隔离等方法避免,我说的带偏是指方向跑偏。

比如说做英语阅读理解,见到一个不认识的词,就去查,这个过程中又见到十个不认识的词,然后又去查,结果一个小时过去了,查了不少单词,但是文章没读几句,题还没做。

你说他没学习,倒也认真学了,但是学着学着方向跑偏了,最后挂科了。

这就是没搞明白目标是啥,这种 DFS 查单词的事情,应该是背单词的时候去做,现在做阅读题呢,目标是快速理解文章内容,选出正确答案嘛。那么几个生僻词汇,影响你对全文内容的掌握吗?

说回学算法,每个人的自身处境不同,需求不同,就应该有不同的学习策略,就像背单词和做阅读两个场景采取两种策略一样。

经常有读者后台留言,让我写一些特别硬核特别难的内容,我都婉言拒绝了;还有的大佬抨击我把算法写成模板是在害人,我也就笑笑不说话。

因为我就很明白咱们讲的这些算法到底是个什么定位,无非就是个锻炼思维能力,准备笔试面试的工具。

需要笔试了,欢迎你来突击学习一下;不需要笔试的话,每天早上地铁上看看,做做思维早操,一天精神好,仅此而已。

大部分读者需要的就是这些,我们号的定位也就是这样。好比初高中的广播体操,就是让学生伸伸胳膊踢踢腿,有益身心健康;你非要说练习后空翻才叫体操,让学生课间练空翻,那估计得出人命了。

从个人的角度,学算法,也要时时刻刻「明白」自己想要的是啥。

如果目标就是从事算法相关的理论研究工作,去啃《算法导论》这种理论性很强的教材完全没问题,反正你还要在学术的路上走很多年,花上一两年打基础性价比挺高。

如果目标是找工作赚钱,那算法就起到个筛选作用,没必要啃大部头,我们号的风格就是你需要的。从各种算法的模板练起,配合历史文章边看边刷,总共可以刷掉将近两百题,国内大厂过算法关没什么问题。节约下来的时间,干点别的不香吗?

说实话我个人更倾向于后者,向钱看齐,那么算法只是个工具。有很多读者纠结于要不要打个竞赛刷个公开课之类的,我觉得大可不必,就好比你跑步,朝着终点直线冲刺最划算,非要跑 S 型秀个蛇皮走位,何苦呢?

人的精力真的是有限的,把每分每秒都压在刀刃上,才能更快达成目标不是么。

当然,不论选择什么,定好目标后都要仔细拆分,严格执行,这个就看个人的执行力了。

本文写了些方法论层面的东西,主要希望大家搞清楚自己学习的目标,制定自己的计划,有自己的思考。不要被乱七八糟的建议牵着鼻子走,今天查一个单词,明天查一个单词,结果到头来挂科了。

如果觉得本文对你有帮助,欢迎关注我的公众号「labuladong」,以后我们除了算法题,可以穿插着聊聊其他话题,比如培养框架思维,求职经历这些,多和大家分享一些个人经历和思考:

不多说了,公众号「labuladong」后台回复「进群」可加入算法群,大家一起刷题 就够了,从现在开始,带你一周之内搞定 LeetCode

目前已本站包含的 150 道题目教程如下

1.两数之和

10.正则表达式匹配

100.相同的树

1011.在D天内送达包裹的能力

111.二叉树的最小深度

1118.一月有多少天

1143.最长公共子序列

130.被围绕的区域

141.环形链表II

141.环形链表

146.LRU缓存机制

167.两数之和 II - 输入有序数组

170.两数之和 III - 数据结构设计

198.打家劫舍

20.有效的括号

204.计数质数

213.打家劫舍II

22.括号生成

222.完全二叉树的节点个数

224.基本计算器

225.用队列实现栈

227.基本计算器II

232.用栈实现队列

234.回文链表

236.二叉树的最近公共祖先

239.滑动窗口最大值

25.K个一组翻转链表

26.删除排序数组中的重复项

28.实现 strStr()

292.Nim游戏

3.无重复字符的最长子串

300.最长上升子序列

312.戳气球

319.灯泡开关

322.零钱兑换

337.打家劫舍III

34.在排序数组中查找元素的第一个和最后一个位置

354.俄罗斯套娃信封问题

355.设计推特

37.解数独

372.超级次方

382.链表随机节点

384.打乱数组

392.判断子序列

398.随机数索引

416.分割等和子集

42.接雨水

43.字符串相乘

435. 无重叠区间

438.找到字符串中所有字母异位词

448.找到所有数组中消失的数字

45.跳跃游戏

450.删除二叉搜索树中的节点

452.用最少数量的箭引爆气球

46.全排列

46.全排列

496.下一个更大元素I

5.最长回文子串

503.下一个更大元素II

509.斐波那契数

51.N皇后

516.最长回文子序列

518.零钱兑换II

53.最大子序和

55.跳跃游戏

56.合并区间

560.和为K的子数组

567.字符串的排列

645.错误的集合

651.四键键盘

700.二叉搜索树中的搜索

701.二叉搜索树中的插入操作

704.二分查找

72.编辑距离

733.图像渲染

752.打开转盘锁

76.最小覆盖子串

77.组合

772.基本计算器III

773.滑动谜题

78.子集

83.删除排序链表中的重复元素

855.考场就座

875.爱吃香蕉的珂珂

877.石子游戏

877.石子游戏

887.鸡蛋掉落

887.鸡蛋掉落

92.反转链表II

969.煎饼排序

98.验证二叉搜索树

986.区间列表的交集

990.等式方程的可满足性

买卖股票的最佳时机 III

买卖股票的最佳时机 II

买卖股票的最佳时机 IV

买卖股票的最佳时机

最佳买卖股票时机含冷冻期

买卖股票的最佳时机含手续费