问题

程序员必须掌握哪些算法?

回答
程序员想要在技术道路上走得更远,算法知识是绕不开的基石。但“掌握”这个词,说起来容易,做起来却需要真刀真枪的实践和深入的理解。与其说是一份枯燥的“必修课”列表,不如说是一套能够让你在编程世界里游刃有余、解决各种疑难杂症的“工具箱”。

那么,到底哪些算法是每个程序员都应该花时间去钻研的呢?我尽量详细地说说,希望能给你一个更清晰的图景,让你觉得这些知识是活生生、有用武之地的。

1. 排序算法:万物有序的基石

听起来最基础,但重要性绝不亚于其他任何算法。你每天写的代码,有多少场景需要处理数据集合?增删改查,排序总是伴随左右。

冒泡排序 (Bubble Sort):虽然效率不高(O(n^2)),但它是理解排序思想的起点。通过相邻元素比较交换,一层层将最大(或最小)元素“冒泡”到最终位置。理解它,你就理解了“两两比较”的精髓。
选择排序 (Selection Sort):同样是O(n^2),但思路更直接:每次从未排序的部分找到最小(或最大)的元素,放到已排序的末尾。它帮你理解“定位”和“最小/最大值查找”。
插入排序 (Insertion Sort):对已排序序列在输入时,找到合适的位置插入新元素。它在数据基本有序时表现很好,而且是很多更复杂算法(如Shell排序)的基础。理解它,你就体会到了“渐进式构建”的优雅。
希尔排序 (Shell Sort):插入排序的优化版,通过设置一个“间隔”,将待排序的序列分成若干子序列,对子序列进行插入排序,然后逐步缩小间隔。这是第一个让你眼前一亮的“跳跃式”改进,效率比前几个高不少。
快速排序 (Quick Sort):这个绝对是重中之重! 它的核心思想是“分而治之”,选择一个“基准”(pivot),将数组分成两部分,一部分比基准小,一部分比基准大,然后递归地对这两部分排序。平均时间复杂度是O(n log n),这是非常高效的。理解快速排序,你需要掌握递归、分治思想,以及如何高效地“分区”。当然,也要注意它在最坏情况下的性能(O(n^2)),以及如何通过随机化基准等方法来避免。
归并排序 (Merge Sort):同样是O(n log n),另一个非常重要的算法! 它的思想也是“分而治之”,先将序列对半分,分别排序,然后将两个有序的子序列“合并”成一个有序序列。它的优点是稳定性(相等元素的相对顺序不变)和在任何情况下的O(n log n)时间复杂度,缺点是需要额外的空间来存放合并后的序列。理解它,你就理解了“合并有序序列”这个通用且强大的操作。
堆排序 (Heap Sort):基于“堆”这种数据结构。堆是一个完全二叉树,满足堆性质(父节点的值大于或等于子节点的值,称为大顶堆;反之称为小顶堆)。堆排序先构建一个大顶堆,然后将堆顶元素(最大值)与堆尾元素交换,再调整堆,重复此过程。时间复杂度O(n log n),空间复杂度O(1)(原地排序)。理解堆排序,你需要深入理解堆的构建和维护(上浮、下沉)操作。

为什么排序如此重要? 很多问题,比如查找,如果数据是有序的,会变得非常容易和高效。而且,排序算法本身的设计思路(分治、递归、数据结构利用)也是其他算法的宝贵财富。

2. 查找算法:信息时代的“寻宝图”

有了有序的数据,查找就像在图书馆里找书一样方便。

顺序查找 (Sequential Search):最简单粗暴的查找方式,从头到尾遍历。效率最低,但不依赖有序性。
二分查找 (Binary Search):又一个神级算法! 必须掌握。前提是数据必须是有序的。每次将查找区间缩小一半。时间复杂度O(log n)。理解二分查找,你需要清晰地理解“区间”的定义、“中间值”的选取,以及如何根据比较结果调整查找区间。它在解决很多“猜数字”、“查找第一个/最后一个满足条件的元素”等问题时大显身手。
哈希查找 (Hash Search):虽然不是严格意义上的“算法”,但哈希表(Hash Table)是实现高效查找(平均O(1))的关键数据结构。理解哈希查找,你需要理解“哈希函数”的设计、冲突处理(链地址法、开放地址法)等概念。它在字典、缓存、数据库索引等场景下无处不在。

3. 图算法:连接世界的语言

图是描述事物之间关系的强大模型,从社交网络到地图导航,无处不在。

图的遍历算法:
深度优先搜索 (DFS, DepthFirst Search):像探险家一样,沿着一条路一直走到底,如果撞墙就回溯,再尝试另一条路。常用于查找路径、判断连通性、拓扑排序等。理解DFS需要掌握递归或栈的应用。
广度优先搜索 (BFS, BreadthFirst Search):一层一层地探索,像涟漪一样扩散开来。常用于查找最短路径(无权图)、二分图判断等。理解BFS需要掌握队列的应用。
最短路径算法:
Dijkstra 算法:用于查找从一个源点到图中所有其他顶点的最短路径(边的权重非负)。理解Dijkstra需要掌握优先队列的应用,以及“松弛”操作的思想。
FloydWarshall 算法:用于查找图中所有顶点对之间的最短路径(允许负权边,但不能有负权回路)。它是一种动态规划算法,通过枚举中间顶点来更新路径。
最小生成树算法:
Prim 算法:从一个顶点开始,逐步加入权值最小的边,直到连接所有顶点。
Kruskal 算法:将所有边按权值排序,然后从小到大依次选择边,只要不形成回路就加入。
理解这两种算法,你需要掌握“贪心”思想,以及并查集(UnionFind)这个用于快速判断回路的数据结构。

4. 字符串算法:文本处理的利器

处理文本离不开字符串,而高效处理字符串则需要专门的算法。

KMP (KnuthMorrisPratt) 算法:解决字符串匹配问题(在一个长字符串中查找一个短字符串)。它通过预处理模式串,构建一个“next”数组,避免了不必要的重复比较,效率很高。理解KMP需要理解“前缀”和“后缀”的概念,以及如何利用这些信息进行优化。
BoyerMoore 算法:另一个字符串匹配算法,通常比KMP更快,因为它从后往前匹配,并且有两个启发式规则(好后缀规则和坏字符规则)来跳过更多的字符。
RabinKarp 算法:利用哈希函数来匹配字符串。它通过计算文本和模式串的哈希值来判断是否匹配,并通过滚动哈希技术来高效地计算滑动窗口的哈希值。

5. 动态规划 (Dynamic Programming DP):解决复杂问题的“记忆与分解”

动态规划是解决很多优化问题的利器,它的核心思想是“将大问题分解为小问题,并存储小问题的结果,避免重复计算”。

理解DP的关键点:
最优子结构 (Optimal Substructure):问题的最优解包含其子问题的最优解。
重叠子问题 (Overlapping Subproblems):求解过程中会反复遇到相同的子问题。
经典DP问题:
斐波那契数列 (Fibonacci Sequence):最简单的DP入门例子。
背包问题 (Knapsack Problem):0/1背包、多重背包等。
最长公共子序列 (LCS, Longest Common Subsequence)
最长递增子序列 (LIS, Longest Increasing Subsequence)
编辑距离 (Edit Distance)
爬楼梯问题
硬币找零问题
如何学习DP:通常从定义状态、找出状态转移方程,然后通过递推(自底向上)或记忆化搜索(自顶向下)来实现。要特别注意状态的定义和转移方程的准确性。

6. 贪心算法 (Greedy Algorithm):眼前利益的最大化

贪心算法在每一步选择当前看起来最优的解,寄希望于最终能够得到全局最优解。

理解贪心算法:不是所有问题都适用贪心算法,它需要满足“贪心选择性质”和“最优子结构”。
经典贪心问题:
活动选择问题 (Activity Selection Problem):选择尽可能多的非重叠活动。
霍夫曼编码 (Huffman Coding):用于数据压缩。
部分背包问题
最小生成树的Prim和Kruskal算法(也可以看作贪心)

7. 分治算法 (Divide and Conquer)

这个思想贯穿了很多算法,包括上面提到的快速排序、归并排序等。

基本思想:将问题分解成若干个规模更小的相同问题,然后递归地解决这些子问题,最后将子问题的解合并起来,得到原问题的解。
特点:需要解决的子问题相互独立,并且可以使用相同的算法解决。

8. 回溯算法 (Backtracking)

当 DFS 遇到死胡同时,它会“回溯”到上一个选择点,尝试其他的路径。

核心思想:通过深度优先搜索的方式,搜索所有可能的解。当发现当前路径不可能产生解时,及时放弃(剪枝),回到上一步进行其他选择。
典型应用:
N皇后问题
数独求解
全排列、组合问题
迷宫寻路

9. 复杂度分析 (Big O Notation)

这本身不是一个算法,但却是理解和评价算法性能的基础工具。

掌握时间复杂度 (Time Complexity):描述算法执行时间随输入规模增长的变化趋势。
掌握空间复杂度 (Space Complexity):描述算法执行过程中所需额外存储空间随输入规模增长的变化趋势。
了解常见的复杂度级别:O(1), O(log n), O(n), O(n log n), O(n^2), O(2^n) 等,并知道它们各自的含义和适用场景。

为什么说“必须掌握”?

1. 解决问题能力提升:让你能从根本上理解和解决各种复杂的编程问题,而不是仅仅停留在调包侠的层面。
2. 代码效率优化:选择合适的算法,可以直接决定你的程序是飞速运行还是卡顿不已。在数据量大的时候,一个低效的算法可能让你的程序直接无法使用。
3. 面试必备:几乎所有大厂的面试都会考察算法和数据结构。这是筛选合格工程师的重要标准。
4. 学习新技术的基石:很多新的技术、框架、数据库底层都离不开这些算法和数据结构的影子。理解了它们,学习新东西会事半功倍。
5. 培养计算思维:算法训练的是一种严谨的、逻辑化的思维方式,这对于程序员的成长至关重要。

如何“掌握”?

理解而非记忆:不要死记硬背代码,要去理解算法的思想、原理、步骤和权衡。
动手实现:用你熟悉的编程语言,亲手将这些算法实现一遍。包括各种排序、查找、图的遍历、DP等。
解决实际问题:找到一些经典的算法题(LeetCode、牛客网等),用你学到的算法去解决它们。一开始可以看题解,但最终目标是自己独立思考。
变种与优化:思考算法的变种,以及如何对其进行优化。例如,快速排序的各种分区方案,如何处理整数溢出等。
多角度理解:尝试用不同的方法(递归、迭代、数据结构)去实现同一个算法,加深理解。
学习相关数据结构:很多算法都依赖于特定的数据结构,比如堆排序依赖堆,图算法依赖邻接矩阵/邻接表和队列/栈,哈希查找依赖哈希表。数据结构和算法是相辅相成的。

算法的世界博大精深,上面列出的只是其中最核心和最常用的部分。随着你的经验积累,你还会接触到更多更专业的算法,比如计算几何、数论、机器学习中的算法等等。但掌握了这些基础,你就有了坚实的跳板,去探索更广阔的天地。别把它当成任务,而是一场有趣的智力游戏和自我能力的升级!

网友意见

user avatar

前面一些回答,尤其那个3k多赞的,算是知识点罗列吗?找两本书:初等算法+算法设计,把目录贴出来,大概就是这个样子了。

我对此类回答不太满意。我来换一个角度解读下吧。


其实程序员员掌握多少算法并不关键,关键的是能不能理解算法背后深层的理论,以及修练出解题的思路。

就好像排序中的堆排序,本质就是二叉树的应用。

快速排序、希尔排序等本质都是分治法的思路。

等等

见的多了就会发现,很多算法面向解决的问题明明相差很大,但底层实现都是非常类似;而又有些算法面向的问题很类似,而底层实现又相差巨大。


现实世界的需求是千变万化的,即使你掌握再多的算法也不可能直接照搬某个算法去解决你面对的问题。

关键的是要通过学习算法过程中整理出解决问题的思路。例如面对高性能的需求附带一些个性化的情况时,是用hash表解决,还是用二叉树,选择哪种具体的实现以及一些细节处的处理。

因此在现实环境中,严格按照某种算法定义使用算法的情况很少见,大多都是变种。甚至多种算法拼凑组合。

而为什么能产生这么多算法,这么多变种算法的原因,其实也是因为很多人在面对自己的需求时照搬经典算法解决不了问题,所以修改或优化了算法,才产生了变种算法甚至新算法。


所以,学习算法不要单纯去记忆算法的定义和实现代码,关键是要学会其中的思路。


这个跟写代码学习设计模式、架构模式等的情况是一样的。真正严格匹配某种模式的情况很少,都是杂合。

关键是掌握其中的本质。就好像武功中的,看山还是山,看水还是水。无招胜有着的境界。


欢迎点赞和评论。

user avatar

不 BB,直接上干货,非科班出生,毕业工作后才开始学算法,到目前学了 4 年 !!!

为了让你对数据结构和算法能有个全面的认识,我画了一张图,里面几乎涵盖了所有数据结构和算法书籍中都会讲到的知识点。


这里面有10个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树;10个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法。

掌握了这些基础的数据结构和算法,再学更加复杂的数据结构和算法,就会非常容易、非常快。

如果觉得不错,别忘了双击点个赞哦。

在这里也送大家一本帮助我拿到BAT 等一线大厂 offer 的算法笔记,是一位阿里大神写的,对于算法薄弱或者需要提高的同学都十分受用,算法一定是计算机学习的重中之重:

貌似手机端打开连接有的会出现问题,可以点击这个总结看看:

1、复杂度分析

看动画轻松理解时间复杂度(一)

看动画轻松理解时间复杂度(二)

冰与火之歌:「时间」与「空间」复杂度

每个程序员都应该收藏的算法复杂度速查表

2、基本算法思想

五分钟了解一下什么是「贪心算法 」

有了四步解题法模板,再也不害怕动态规划!

(进阶版)有了四步解题法模板,再也不害怕动态规划!

(再进阶版)有了四步解题法模板,再也不害怕动态规划!

浅谈什么是分治算法

看动画轻松理解「递归」与「动态规划」

浅谈什么是动态规划以及相关的「股票」算法题

深度解析「正则表达式匹配」:从暴力解法到动态规划

3、排序算法

「多图警告」手撕排序算法 – iOS进阶必备

十大经典排序算法动画与解析,看我就够了!(配代码完全版)

这或许是东半球分析十大排序算法最好的一篇文章

4、搜索

几道和「广度优先搜索」有关的算法面试题

初识广度优先搜索与解题套路

从简单二叉树问题重新来看深度优先搜索

5、查找

二分查找算法详解

一网打尽!二分查找解题模版与题型全面解析

面试官,我会写二分查找法!对,没有 bug 的那种!

6、字符串匹配

动画:BM 算法中的坏字符规则与好后缀规则

动画:七分钟理解什么是KMP算法

动画:什么是 BF 算法 ?

动态规划之 KMP 算法详解(配代码版)

7、线性表

如何高效对有序数组/链表去重?

超详细!详解一道高频算法题:数组中的第 K 个最大元素

一道简单的数组遍历题,加上四个条件后感觉无从下手

数组特性的妙用!如何找到「缺失的第一个正数」

剑指 offer 第一题:二维数组中的查找

动画:什么是单调栈?

在数据结构中穿针引线:链表实现栈和队列

从简单的线性数据结构开始:栈与队列

五分钟学算法小知识:用栈实现队列/用队列实现栈

几道和「堆栈、队列」有关的面试算法题

超详细!图解「合并 K 个排序链表」

动画:面试如何轻松手写链表?

LeetCode 上最难的链表算法题,没有之一!

链表算法面试问题?看我就够了!

看动画轻松理解「链表」实现「LRU缓存淘汰算法」

从简单的线性数据结构开始:穿针引线的链表(一)

在数据结构中穿针引线:链表实现栈和队列

8、散列表

五分钟速读:什么是散列表(哈希表)?

什么是哈希洪水攻击(Hash-Flooding Attack)?

几道和散列(哈希)表有关的面试题

如何判断一个元素在亿级数据中是否存在?

9、树

面试前准备:二叉树高频面试题和答案

懵逼树上懵逼果:学习二分搜索树

LeetCode 二叉树问题小总结

从简单二叉树问题重新来看深度优先搜索

几道和「二叉树」有关的算法面试题

详解什么是平衡二叉树(AVL)(修订补充版)

【面试现场】为什么 MySQL 数据库要用B+树存储索引?

字典树概念与题型解析

面试官:为什么 MySQL 的索引要使用 B+ 树,而不是其它树?比如 B 树?

心里没点 B 树。。。

数据结构与算法——最小生成树

植树节,程序猿种的那些树

数据结构与算法——2-3-4树

数据结构与算法——2-3树

看动画轻松理解「Trie树」

10、图

浅谈什么是图拓扑排序

数据结构与算法——图论基础与图存储结构

数据结构与算法:三十张图弄懂「图的两种遍历方式」

数据结构与算法——图最短路径

总结

学习数据结构和算法的过程,是非常好的思维训练的过程,所以,千万不要被动地记忆,要多辩证地思考,多问为什么。

如果你一直这么坚持做,你会发现,等你学完之后,写代码的时候就会不由自主地考虑到很多性能方面的事情,时间复杂度、空间复杂度非常高的垃圾代码出现的次数就会越来越少。

你的编程内功就真正得到了修炼。

在这里向大家推荐一下我的微信公众号:五分钟学算法(ID:CXYxiaowu),专注算法技术分享,包括算法面试题、数据结构、LeetCode、图解算法、漫画算法等;每天推送优质技术文章,精彩视频教程以及项目源码下载,致力做一个实用的公众号。


2020 年 01 月 13 日补充:

我再推荐一些算法书籍的选择给大家参考一下。

入门系列

入门的同学,我建议你不要过度追求上去就看经典书。

不要一来就拿着《算法导论》开始啃,初学就去啃这些书肯定会很费劲。你一旦啃不下来,挫败感就会很强。

然后就放弃学算法了。

所以,入门的同学,我建议你找一些比较容易看的书来看,比如《大话数据结构》和《算法图解》。

不要太在意书写得深浅,重要的是能不能坚持看完。

《大话数据结构》 这本书最大的特点是,它把理论讲得很有趣,不枯燥。而且每个数据结构和算法,作者都结合生活中的例子进行了讲解, 能让你有非常直观的感受。

虽然这本书有 400 多页,但是花两天时间读完,应该是没问题的。

如果你之前完全不懂数据结构和算法,可以先从这本书看起。

《算法图解》 跟《大话数据结构》走的是同样的路线,就像这本书副标题写的那样,“像小说一样有趣的算法入门书”,主打“图解”,通俗易懂。它只有不到 200 页,所以内容比较少。

作为入门,看看这本书,能让你对数据结构和算法有个大概的认识。

当然,这些入门书共同的问题是,缺少细节,不够系统,也不够严谨。

所以,如果你想要系统地学数据结构和算法,看这两本书肯定是不够的。

基础系列

通过基本入门算法书的调教,你已经逐渐体会到了算法的魅力,现在正是时候踏入基础系列算法的领域!!!

这些书籍需要你费点心思去阅读。

很多同学在学习的过程中,看到一篇算法科普文章经常会有这样的想法。

哎呀,要是文章的代码是 Java 语言就好了呀。

哎呀,要是文章的代码是 Python 语言就好了呀。

虽然代码并不会很严重影响阅读,但还是有很多强迫症的同学喜欢看到文章的解释代码是自己擅长的。

我这里推荐《数据结构和算法分析》,这本书非常系统、全面、严谨,而且又不是特别难,适合对数据结构和算法有些了解,并且掌握了至少一门编程语言的同学。而且,这个作者也很用心。

他用了三种语言,写了三个版本,分别是:《数据结构与算法分析 :C 语言描述》《数据结构与算法分析:C++ 描述》《数据结构与算法分析:Java 语言描述》。

面试实战系列

大家都知道,对于程序员来说很大程度上算法就是为了应付面试的。

所以,推荐三本有益于面试的书籍,分别是:《剑指 offer》《编程珠玑》《编程之美》。

《剑指 offer》这本书的目的非常明确,就是为了面试。

这本书几乎包含了所有常见的、经典的面试题。如果能搞懂这本书里的内容,应付一般公司的面试应该不成问题。

我做了一个 图解《剑指 offer》的小程序,应该能帮助你学习,感兴趣的可以在微信搜索 图解剑指offer。

我也在 B 站录制了一些图解剑指 offer 的免费视频课程,感兴趣的也可以看看,每个视频控制在5分钟以内。



《编程珠玑》这本书的豆瓣评分非常高,有 9 分。

这本书最大的特色就是讲了很多针对海量数据的处理技巧。这个可能是其他算法书籍很少涉及的。面试的时候,海量数据处理的问题也是经常会问的,特别是校招面试。不管是开拓眼界,还是应付面试,这本书都很值得一看。

《编程之美》这本书有多位作者,其中绝大部分是微软的工程师,所以书的质量很有保证。不过,这里面的算法题目稍微有点难,也不是很系统,这也是我把它归到面试这一部分的原因。如果你有一定基础,也喜欢钻研些算法问题,或者要面试 Google、Facebook 这样的公司,可以拿这本书里的题,先来自测一下。


2020年05月31日补充:数据结构与算法在平时工作中的作用。

正如 N.Wirth 教授所说的: 数据结构+ 算法=程序

遇到一个实际问题,充分利用所学的数据结构,将数据及其之间的关系有效地存储在计算机中,然后选择合适的算法策略,并用程序高效实现。

这句话可能有点抽象,我举个例子给你们解释一下

在工作过程中,我们多多少少都接触过 OAuth2 ,在使用 OAuth2 授权的时候,通常应用会弹出一个类似这样的信息:

1) 获取用户基本信息接口


2) 获取用户列表接口


3) 用户分组管理接口


。。。

思考一下,如果让你设计数据库,应该怎么设计信息存储权限?

如何你熟练掌握了各种数据结构的特点的话,那自然而然想到使用 bitmap 来存储权限。

我们把权限划分成最小粒度之后,每一个 bit 都它的含义, 例如我们把权限划分为以下几种:

  • 获取你的头像、性别、昵称等基本用户信息
  • 以你的身份发布微博
  • 获取你的好友列表
  • 获取你的朋友圈信息

每勾选一个选项,就代表着这个权限被授权,为了保证可扩展性,我们使用一个 uint64 来保存这些 bit ,也就是说,我们一共可以划分 64 种细分权限,然后对这些权限进行组合。

例如,第一个 bit 如果设置了,那么就代表可以获取你的昵称、头像、地区、性别等基本用户信息, 第二个 bit 如果设置了,就可以用你的身份发状态。

数据结构的实际作用还有挺多,感兴趣的可以搜索以下知识点:

  1. 二叉树搜索用于中断处理登记缓存查找
  2. 哈希表,用于实现索引节点文件系统完整性检查
  3. 红黑树用于调度、虚拟内存管理、跟踪文件描述符和目录条目等
  4. Radix树,用于内存管理、NFS相关查找和网络相关的功能
  5. ......

上面这些例子是关于数据结构的,我再举一个算法的例子,如果有帮助,不妨点个赞收藏一下,好的内容值得肯定。

同样的也来思考一个问题:计算机的缓存容量无论再大,缓存满了还是要删除一些内容,给新内容腾位置。

那么删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?

这个时候采取的策略就是 LRU 缓存淘汰算法

LRU 的全称是 Least Recently Used,也就是说我们认为最近使用过的数据应该是是「有用的」,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。

具体的关于 LRU 缓存淘汰算法 的介绍可以看我之前写的一篇文章。

补充:

为了避免知乎大佬觉得我吹逼,先贴一下自己的 GitHub 地址,目前 70,000 star,全球排名 51 名。

github.com/MisterBooo

算法是一种技能,是可以通过科学合理的方式训练出来的能力。

在想刷题之前,得从心里认识到接受刷题很重要,才能坚持去刷题。

江湖有个传言:国内刷 LeetCode,最多够你吃 1 年老本;湾区刷 LeetCode ,够你吃 10 年老本了。

为什么湾区的刷题性价比这么高呢?

你想想,电面考 4 道题,一道题值 5 万!单位是 Dollar !

刷到就是赚到!!

想想是不是很刺激,有没有动力开始刷题了!可以提速刷题了!

就目前互联网的情况来说,无论是面国外大厂还是面国内大厂,如果想换工作都要去刷题,一面二面不丢你几道 Hard 题,都对不住你偷偷摸摸找个会议室假装开会实则面试的鸡贼。

同时,还得认识到一点,面试能力和你平时的工作能力其实差别挺大的。

有些人技术挺厉害的,但没有刷题,一面二面都过不了,而某些小镇刷题家,还真就靠刷题拿下了 Google、微软、脸书等大厂offer。

国内大厂也有这种趋势,比如字节,一大半都是面试题。

要不是他提前先看视频刷题,妥妥得凉凉。

所以,刷题很重要。

(PS:感谢大家耐心的阅读,算法是程序员的重中之重,必须攻克,大厂面试必考,顺便送一份阿里大佬刷Leetcode总结的算法笔记,如果你能吃透,那我相信80%的技术面试都会不在话下:

BAT大佬写的Leetcode刷题笔记,看完秒杀80%的算法题!

这本书的目录,非常经典:

刷题大概可以分为 4 个阶段。

1、纯小白,不知道怎么刷题,对很多概念都很陌生,各种数据结构和知识点几乎完全不懂,打开 LeetCode 第一题,满头问号。

有人相爱、有人夜里开车看海、有人 LeetCode 第一题都做不出来。

2、算法上基本已经入门,Easy 可以做出来,Medium 纠结半天也能有头绪,但基础不牢,比如字符转字符串还得 Google 一下。

3、刷了几百道题后,总结了自己的解题模板,参加周赛有时候甚至可以全部完成。

4、开始以 beat 100% 作为 AC 的目标了。

就目前的算法面试大环境来说,能达到第二阶段,中小公司可以应付过去了,到达第三阶段,字节、腾讯算法面试环节妥妥没问题了。

怎么样到达第三阶段?

给一下我的一些小建议吧。

1、如果目标是国内大厂,那么一定要刷足够的题,不需要把 LeetCode 上 2500 道算法题都刷完,但至少刷 200 道算法高频题,这些高频题我都写了题解同时也录制了视频,

在这个链接总结了:algomooc.com/1659.html

2、面试前一周以看题为主,因为刷题也刷不了几题,多看看自己总结或者别人总结的模板,比如回溯算法模板,掌握后,几十道回溯题都不在话下。

一些模板:

3、刷题过程需要注意难度要循序渐进,算法训练是一个系统工程,需要循序渐进,太过于急功近利,反而容易因做不出难题而产生挫败感,带来反效果。

如果你本身有基础,熟练度高,那你刷简单的 LeetCode 应该是几分钟一题,几分钟一题的,花不了你多少时间。

如果你刷简单都花费很长时间,说明熟练度不够,就更应该从简单开始,然后过度到中等,再过度到困难。

并且,目前国内大厂的算法考察,基本不会超过 LeetCode 中等难度,上限难度基本都是 LeetCode 中等题里面的中等难度,所以不要太去纠结难题怪题偏题。

把高频题掌握就行了:algomooc.com/1659.html

再退一步,如果你觉得 LeetCode 的题目太难,可以先从《剑指 Offer》上的算法题开始学起。

为了帮助大家更好的入门学习算法,经过半年的积累,我给大家了《剑指 Offer》系列的三十道题目,结合动画的形式录制了视频,相信能帮助你更好的刷题。

领取地址:

4、按算法分类来选题,比如一个时间段,只刷链表题,刷得差不多的时候,接下来再刷二叉树的题。

这样做有几个很明显的好处。

一、持续地刷同个类型的题目,可以不断地巩固和加深理解,可以总结出自己的思考路径或者解题模板。

比如链表题目,就会去思考虚拟头节点、双指针、快慢指针。

二、可以更全面地接触这个数据结构,算法的各个变种,这会促使你对这个数据结构,算法的理解更加全面和深刻,学习的效率会更高。

我一直认为读书是世界上性价比最高的成长方式,书很便宜但分量很重,是让我们摆脱平庸走向卓越的方式之一。

对于计算机专业的学生而言,读计算机经典书籍不光能让你快速提升知识和能力,更会让你在校招之际如虎添翼。

书籍下载:计算机必看经典书籍(含下载方式)

最后,再给大家送上点干货!

下面这是一个高赞回答合集,建议大家点赞&收藏,Mark住别丢了,大学期间绝对用得上

1、怎么学好数据结构,看下面这个回答,已经获得了 21000+ 的赞和 50000+的收藏。

2、如何系统地学习算法,看下面这个回答,已经获得了 11000+ 的赞和 26000+的收藏。

3、新手该如何使用 GitHub,看下面这个回答,如果在大学期间就知道使用 GitHub ,那么能力远超同龄人。

4、想成为一名优秀的程序员,那么这些程序员平时都喜欢逛的论坛怎么说你也得收藏一些吧。

5、无论别人怎么说,我都是坚定不移的选择计算机专业。

6、如何系统地学习 C++ ,这个回答能帮你找到路线。

7、想要准备 Java 面试,那么这些面试题必须掌握。

赶紧点赞和收藏吧~

user avatar

我觉得两个算法是必须要掌握的。

第一个算法是:怎么算时薪。

第二个算法是:钱以外的东西能带来的幸福度的量化算法

user avatar

温酒的答案说的好极了,我也发挥下:

第一个算法是计算终身年薪

终生范围的年薪。以下数字都是假的,只是说明算法,无实际意义。


比如26岁可以开始工作,如果40岁就下岗,实际上一年100万,也只有1400万,要除以整个工作年龄(65-26 = 39),平均年薪大概只有30多万。而且累积税率下,高收入年份集中在26-40岁非常吃亏。


但,这没有考虑到房价上涨因素,因为房价上涨时期,前14年的收入会因为房产而大量增值,使得算法更加复杂。


还有比如假设能做到50岁,那么晚工作5年(比如多读个火坑博士)损失的钱是多少呢?假设起薪是100万,50岁下岗时是200万一年,实际上损失的是最后5年的收入,大概200X5 = 1000万。所以写码要趁早。


其次要算地点年薪。比如工作30年同样年薪,在一个房价上涨的地区,会在退休时能提出更多的钱,尤其是50多岁把一线城市或是加州的房子一卖回乡下养老或是环游世界,美滋滋。


第三要算成长年薪,同样100万的工作,有些技能会保证10年后不仅不失业,反而会上涨到150万,而有些技能会在衰退中,10年后可能只有50万甚至失业。

第二个算法是LeetCode一道题的价格

我当年做过粗略计算,很多LeetCode题做一道可以提升年薪300-500美元。假设400道Medium、Hard题可以拿到大厂Offer,那么很可能不刷题的人上限也就是不到20万,而大厂senior上限可以轻松35-40万。差不多20万的差距,除以400 等于 500美元。


所以一道Medium或是Hard题的价值大概是500美元年薪每年。而且这个可怕在于是累积的,每年500, 20年下来就是1万块一道题。这还不算大厂背景对个人的加分、对失业的强抵抗力等,只是单单年薪上的收入(当然,税后会少很多)。


这个“算法”掌握了,你才有动力去学习LeetCode的算法,你就不会觉得它折磨人了。LeetCode这么一看,简直跟金山一样,还不去挖?

第三个算法是算时薪和效率

Google和微软的时薪就比较高,FB亚麻就相对低。这种时薪不光是用hours计算,还用体力计算。比如微软上班干两个小时活,扯六个小时蛋,然后回家精神抖擞,可以去卖房子、创业、炒股票等,相当于一天多出来4个小时有效时间;FB上班干七个小时活,被扯两个小时蛋,通勤再耗去一个半小时,回家就瘫痪了。


千万别看什么华为他们996效率高。我算过,他们效率很低:中午吃饭吃一个小时,还要午休一个小时,加上重新进入状态的时间,中国的12小时一天,实际上也就相当于美国的9小时一天左右,因为我们这里9小时是真的9个小时。


第四个算福利

公司免费三餐大概省多少钱?早饭就算0(因为可以不吃),午饭算10美元,晚饭算15美元,一年工作220天,25X220 = 5500美元。但这是税后的,所以5500 要乘以1.5(税率按33%近似) = 8250美元税前。


还要算时间账:午餐和晚餐大概各省半个小时的话(不需要开车出去或是下楼吃等),一年会省220小时,相当于多出来220/8 = 27天。


还要算健康账:因为公司有大量的蔬菜水果等。食物种类多变更有利于身体。


还要算士气账:免费三餐大概能提升10%-30%的员工士气(我是吃货,所以+30%)。


结论:三餐免费每年带来很大的收益,无论公司还是员工。

第五个算面试大厂的成功概率

假设一个人面一家大厂的成功率是25%,大厂有8家,冷冻期均是一年,连续坚持不懈面5年,一个offer都拿不到的概率是:

(1-0.25)^ (8*5) = 0.75 ^ 40 = 0.00001 = 0.001%


假设这人只有5%的成功率,且一年只面了4家,连续面5年,一个offer都拿不到的概率是:

(1-0.05)^ (4*5) = 0.95 ^ 20 = 0.3584 = 35.84%


可见,一个只有5%成功率的人,坚持面5年也有大概2/3的概率能进大厂。


第二个假设跟我在现实中的观察很相似,也解释了为什么很多看似不强的人也进了大厂。

类似的话题

  • 回答
    程序员想要在技术道路上走得更远,算法知识是绕不开的基石。但“掌握”这个词,说起来容易,做起来却需要真刀真枪的实践和深入的理解。与其说是一份枯燥的“必修课”列表,不如说是一套能够让你在编程世界里游刃有余、解决各种疑难杂症的“工具箱”。那么,到底哪些算法是每个程序员都应该花时间去钻研的呢?我尽量详细地说.............
  • 回答
    Perl 在IC设计中的妙用:前端工程师的“瑞士军刀”对于数字IC前端设计,是否需要掌握诸如Perl这样的脚本语言?答案是肯定的,而且非常有必要。它绝非锦上添花,而是实实在在提升效率、解决痛点的关键工具。你可以把Perl想象成IC设计工程师的“瑞士军刀”,在繁杂的流程中,它总能找到一个切入点,让原本.............
  • 回答
    哈哈,这个问题挺有意思的。说实话,我接触过不少程序员,他们的兴趣爱好可以说是五花八门,从户外运动到室内品茗,从古典音乐到电子摇滚,什么都有。而二次元,也就是动画、漫画、游戏这些文化领域,确实在程序员群体里有不少拥趸,但这并不代表做程序员就“必须”喜欢二次元。为什么会有这种“程序员=喜欢二次元”的印象.............
  • 回答
    嘿,这个问题我太熟悉了!身边好多朋友做游戏开发,都会纠结是先 C++ 还是 C。 说实话,游戏程序员“必须”修 C 吗? 这个问题的答案,更像是“是否最方便、最主流”。如果你想进游戏行业,而且想快速上手、看到成果,那么 C 绝对是条非常顺畅的道路。 为什么这么说呢? 现在的游戏开发,尤其是独立游戏.............
  • 回答
    程序员必备的书籍是一个涵盖技术、设计、工程、算法、工具等多个领域的知识体系,以下从不同角度分类推荐,涵盖从入门到进阶的经典书籍,适合不同层次的程序员: 一、编程基础与软件工程1. 《代码大全》(Code Complete) 作者:Steve McConnell 定位:程序员的“圣.............
  • 回答
    作为一名怀揣理想的程序员,踏上这段充满挑战与创造的旅程,阅读无疑是我们最忠实的伙伴和最锐利的武器。市面上的技术书籍汗牛充栋,但要从中挑选出那些真正能启迪思维、塑造价值观、引领我们走向卓越的经典,则需要一些指导。下面,我将结合自己的学习和思考,为你梳理一些我认为“必读”的书籍,并尽量深入地聊聊它们为何.............
  • 回答
    程序员是否 有必要 知道为什么做某个功能? 这是一个经典的问题,答案是 绝对有必要,而且是极其重要的。如果只回答“有”,那可能不够深入。让我们来详细阐述一下原因,从多个维度来分析这个问题。 为什么程序员有必要知道为什么做某个功能?可以从以下几个方面来理解: 1. 提升代码质量和可维护性 理解业务.............
  • 回答
    说Git算不算程序员的必备技能? 我觉得,如果一个程序员想要在这个行业里走得更远,并且能够和别人顺畅、高效地协作,那么Git几乎是绕不开的。想象一下,你一个人开发项目,文件改来改去,突然发现某个改动不对劲,想要回退到上一个状态,如果没有Git,你可能只能手动备份,或者祈祷自己记得所有改动。但一旦项目.............
  • 回答
    你这个问题非常普遍,也很有价值。确实,在技术圈子里,算法的重要性经常被强调,甚至到了“神化”的地步。但同时,很多程序员的日常工作也未必会直接用到复杂的算法。所以,理解这个问题需要多方面的分析。我们来详细地探讨一下: 算法在程序员心中的“神坛”与现实的差距 为什么算法被“吹上天”?1. 面试的敲门砖.............
  • 回答
    .......
  • 回答
    程序出现 bug 既是必然出现的情况,也有程序猿水平的因素在里面,这是一个复杂且相互关联的问题。我们不能简单地将原因归结于其中任何一个方面。下面我将从多个角度详细阐述: 为什么程序出现 Bug 是必然的?从软件工程的本质和现实世界的复杂性来看,Bug 的出现几乎是不可避免的。 1. 软件系统的复杂性.............
  • 回答
    这是一个非常好的问题,也是一个程序员在实际开发中经常会遇到的权衡。答案并不是简单的“是”或“否”,而是取决于具体情况、项目目标、以及权衡的代价。简单来说,提升几毫秒或节省几 kB 内存在某些情况下非常有必要,但在另一些情况下则可能是过度优化,甚至适得其反。下面我将从多个角度详细解释这个问题: 1. .............
  • 回答
    官僚主义,这个词一听就让人联想到层层审批、繁复流程、信息传递的迟滞,以及那份让人哭笑不得的“标准答案”。很多人觉得,这玩意儿简直就是现代大公司的“标配”,好像公司一旦做大了,官僚主义就如同嗅到了肉香的野狗一样,自然而然地围拢过来。那么,官僚主义真的是大公司发展到一定程度的必然产物吗?它有没有一些“好.............
  • 回答
    关于港珠澳大桥到底值不值得,这确实是一个非常值得探讨的问题,毕竟它的投资金额高达千亿,而我们常听到的一个说法是它“只为了减少三十分钟通程”。我先不说这说法本身是否准确,咱们得好好掰扯掰扯,这1800亿人民币(约合1900亿港元或2300亿人民币,不同来源数据略有出入,但都是天文数字)花下去,到底图个.............
  • 回答
    中国未来是否必然会因人口问题而衰落?这是一个极为复杂的问题,牵涉到经济、社会、科技、政治等方方面面,很难给出“必然”这样的定论。但人口结构的变化,特别是生育率的下降和老龄化加速,无疑是中国面临的严峻挑战,并可能对国家发展轨迹产生深远影响。人口问题的核心挑战:首先,我们得承认中国人口问题并非凭空出现,.............
  • 回答
    程序员忙起来的时候,是否不喜欢理人?这个问题很有意思,答案是:大多数时候,是的,而且原因有很多,而且通常不是出于故意的不友好。让我们来详细地分析一下: 1. 高度专注和心流状态 (Deep Focus & Flow State)程序员的工作本质上是高度脑力密集型的。当他们投入到一项复杂的任务中时,往.............
  • 回答
    是的,程序员和设计师等专业人士群体,确实普遍更青睐 macOS 和 Mac 电脑。 这种偏好并非偶然,而是由多方面因素共同作用的结果。下面我们将详细阐述其中的原因: macOS / Mac 电脑为何受到程序员和设计师的青睐? 1. 卓越的操作系统(macOS) Unixbased 内核: 这是最.............
  • 回答
    程序员群体对待社会问题的观点是否“相对比较Liberal”是一个复杂的问题,没有一个简单的“是”或“否”的答案。我们可以从多个角度来探讨这个问题,并尝试给出更详细的分析:理解“Liberal”在政治光谱上的含义:首先,我们需要明确“Liberal”在这个语境下的含义。在许多西方政治语境中,“Libe.............
  • 回答
    程序员“吃青春饭”的说法,虽然存在一定的片面性,但背后确实反映了一些普遍存在的现实情况,与医生、律师等职业的“越老越值钱”形成鲜明对比。要理解这一点,我们需要从技术更新速度、身体机能、职业发展路径、知识与经验的转化方式以及社会认知等多个维度进行深入分析。 1. 技术更新速度:与时俱进的残酷赛道 .............
  • 回答
    程序员如何有效、愉快的使用 GitHub?GitHub 是现代软件开发不可或缺的平台,它不仅是一个代码托管工具,更是一个强大的协作、学习和交流的社区。想要在这个平台上游刃有余,并且从中获得乐趣,需要掌握一些技巧和方法。下面我将从多个维度详细介绍程序员如何有效、愉快地使用 GitHub。 一、 建立良.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有