算法——占据面试比重 75%!盘点程序员必备 10 大算法
Posted 一起学编程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法——占据面试比重 75%!盘点程序员必备 10 大算法相关的知识,希望对你有一定的参考价值。
导语:
在程序员圈子里,经常讨论哪家大厂的算法如何厉害。那么,算法这个让程序员情感复杂的东西,到底“厉害”在何处?算法对于程序员是否重要?作为一个合格的程序员,应该掌握哪些算法?本期,就和大家一起探索,“算法到底是什么”。
应对灯泡不亮的算法流程图
算法的前世今生
算法(algorithm)作为在数学(算学)和计算机科学之中的一个有效方法,是一个被定义好的、计算机可施行指示的有限步骤或次序,常用于计算、数据处理和自动推理。它包含了一系列定义清晰的指令,并可于有限的时间及空间内清楚的表述出来。
用通俗的方式来理解,可以把算法比作食谱。让对烘焙一无所知的人,也可以根据食谱上所提供的“算法”步骤,按比例混合材料,用适当的和面力度,控制烤制时间,做出美味的面包。
同时,每一次烤制面包,都不需要重新研究烘焙的方法。这也是“算法”的初步特征:算法是解决问题的手段。我们不需要为每个同类问题,都发明一个解决方案。因此,算法是一劳永逸式的工作方法。
离开如今狭义的互联网术语,在千年之前,人们关于算法的探索就已经开始,在中国古代,算法被称为“术”。最早出现在《周髀算经》、《九章算术》。特别是《九章算术》,给出四则运算、最大公约数、最小公倍数、开平方根、开立方根、求素数的埃拉托斯特尼筛法,线性方程组求解的算法。
西方世界,大约公元前300年,欧几里得算法出现,被人们认为是史上第一个算法。时间来到1842年,爱达·勒芙蕾丝为“巴贝奇分析机”编写求解“解伯努利微分方程”的程序,因此爱达·勒芙蕾丝被大多数人认为是世界上第一位程序员。紧接着,20世纪的英国数学家图灵提出了著名的图灵论题,并提出一种假想的计算机的抽象模型,这个模型被称为图灵机。
也是从图灵机开始,算法真正在计算机领域开始应用。对于算法的“前世”有所了解,那么“今生”的算法对于程序员究竟有多重要呢?
从广义来讲,算法从数学、逻辑学,甚至是编程哲学的角度,对每个学习者及应用者产生影响。它虽然不是学来就用的东西,但对于程序员,重要到决定了他们可以在这个行业里走多远的程度。
对于程序员,算法是方法、思想,是一种解决问题的思维方式。就像是食谱,它锻炼你遇到有序的问题时,以计算机的“思维方式”,利用规律的特性来解决问题。在不断优化程序员的编程思维。在未来的工作中,也许程序员不会用到形式上的算法,但这种底层方法论已融入到程序员的工作思维里面。
在实际工作中,需要去阅读一些代码的时候,也确实需要算法功底,例如在看leveldb、redis源代码时,需要知道跳表是什么意思;看Linux vma要知道红黑树是什么;看page cache要懂得基数树。
最后,无论程序员多么抗拒算法,但也要有所学习来应对面试。
在程序员面试中,有75%的题目都会与算法、数据结构相关,尤其是国外的一些公司,算法是面试中考察的重中之重,尤其是国外管理者特别喜欢那些ACM竞赛经验的面试者。面试时,当面试官忽然一句“关于算法,你……”的问题抛来,面试者无法应对,可能便直接凉凉回家。
10个程序员要知道的算法
在程序员的日常工作中,有以下十个程序员要知道的基础算法。
1.快速排序算法
快速排序是由东尼·霍尔所提出的一种排序算法。在平均状况下,排序n个项目要Ο(nlogn)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。快速排序通常明显比其他Ο(nlogn)算法更快,因为它的内部循环(innerloop)可以在大部分的架构上很有效率地被实现出来。
2.堆排序算法
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序的平均时间复杂度为Ο(nlogn) 。
3.归并排序
归并排序(Mergesort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(DivideandConquer)的一个非常典型的应用。
4.二分查找算法
二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。
搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束,如果某一特定元素大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。
如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn) 。
5.BFPRT(线性查找算法)
BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度。
该算法的思想与快速排序思想相似,当然,为使得算法在最坏情况下,依然能达到O(n)的时间复杂度,五位算法作者做了精妙的处理。
6.DFS(深度优先搜索)
深度优先搜索算法(Depth-First-Search),是搜索算法的一种。
它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。
这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
7.BFS(广度优先搜索)
广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。
如果所有节点均被访问,则算法中止。BFS同样属于盲目搜索。一般用队列数据结构来辅助实现BFS算法。
8.Dijkstra算法
戴克斯特拉算法(Dijkstra’salgorithm)是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出。
迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一个最短路径树。该算法常用于路由算法或者作为其他图算法的一个子模块。
该算法的输入包含了一个有权重的有向图G,以及G中的一个来源顶点S。以V表示G中所有顶点的集合。
每一个图中的边,都是两个顶点所形成的有序元素对。(u,v)表示从顶点u到v有路径相连。我们以E表示G中所有边的集合,而边的权重则由权重函数w:E→[0,∞]定义。因此,w(u,v)就是从顶点u到顶点v的非负权重(weight)。
边的权重可以想像成两个顶点之间的距离。任两点间路径的权重,就是该路径上所有边的权重总和。已知有V中有顶点s及t,Dijkstra算法可以找到s到t的最低权重路径(例如,最短路径)。
这个算法也可以在一个图中,找到从一个顶点s到任何其他顶点的最短路径。对于不含负权的有向图,Dijkstra算法是目前已知的最快的单源最短路径算法。
9.动态规划算法
动态规划(Dynamicprogramming)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。
通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。
关于动态规划最经典的问题当属背包问题。
10.朴素贝叶斯分类算法
朴素贝叶斯分类算法是一种基于贝叶斯定理的简单概率分类算法。贝叶斯分类的基础是概率推理,就是在各种条件的存在不确定,仅知其出现概率的情况下,如何完成推理和决策任务。
概率推理是与确定性推理相对应的,而朴素贝叶斯分类器是基于独立假设的,即假设样本每个特征与其他特征都不相关。
朴素贝叶斯分类器依靠精确的自然概率模型,在有监督学习的样本集中能获取得非常好的分类效果。在许多实际应用中,朴素贝叶斯模型参数估计使用最大似然估计方法,换言之朴素贝叶斯模型能工作并没有用到贝叶斯概率或者任何贝叶斯模型。
尽管是带着这些朴素思想和过于简单化的假设,但朴素贝叶斯分类器在很多复杂的现实情形中仍能够取得相当好的效果。
了解到算法的重要性,是否有兴趣加强一下算法学习呢?但别着急,算法从诞生到如今为人们应用,走过了千年时光。我们从学习到得心应手,也不是一朝一夕便能做到。
最后还有句话是这么说的:栽一棵树最好的时间是十年前,其次是现在。对于学习编程或者在工作想升职的程序员,如果你想更好的提升你的编程核心能力(内功),在面试时有充分的准备和自信!笔者这里或许可以帮到你~
C语言C++编程学习交流圈子,QQ群:765803539【点击进入】微信公众号:C语言编程学习基地
分享(源码、项目实战视频、项目笔记,基础入门教程)
欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
编程学习视频分享:
以上是关于算法——占据面试比重 75%!盘点程序员必备 10 大算法的主要内容,如果未能解决你的问题,请参考以下文章
算法 | 第4章 树与图相关《程序员面试金典》#yyds干货盘点#
#yyds干货盘点# LeetCode程序员面试金典:最小高度树
算法 | 第3章 栈与队列相关《程序员面试金典》#yyds干货盘点#
算法 | 第5章 位操作相关《程序员面试金典》#yyds干货盘点#