关于算法有太多的疑问和截然相反的争论,例如经常看到很多人说算法是玄学,是聪明者的游戏,学不好是自己笨,数学不好所以算法不会等等。还有人会觉得工作不用所以不学,算法不用学,在工作中多积累积累就行了吗?还有人总是感觉各种算法课程没有用,这都是为什么呢?

我们继续谈。

我们前面说面试以数据结构及其变形为主,这能占到现场手写算法的80%,那这些内容到底有哪些呢?高级和初级算法怎么区分呢?

我们先回忆一下数据结构都有哪些内容。如果你学过数据结构课程,你应该知道大致有那么几个章节:数组(包括一维和二维)、链表(包括单链表、双链表、循环链表)、队列、栈、Hash与集合、树(包括二叉树、AVL树、N叉树、堆、红黑树、哈夫曼树、B*树等等)、图以及数据结构的两个基本问题 查找(主要是二分查找)和排序(若干常见排序策略)。此外还有三个不是数据结构,但是结构特殊一般需要我们特殊对待的结构字符串、位图和数字。

现在我们来看,这些问题哪些是工作中经常用的,或者说是怎么用的。

1.对于数组,算法里常用int []array和int [][]array来表示一维和二维数组,而在算法里我们更多是采用List<Object>和List<List<Object>>这种方式来表示一维和二维数组结构,例如处理Excel等等就会这么做。为什么不一样呢?因为前一种方式更简洁,而且与语言无关。而后者则可以充分利用List等类的基础接口提高我们的开发效率和程序的稳定性。

2.再看链表,我的映像中极少会使用java写链表的代码,更多是采用组合和List等方式解决实际问题,也许只有在责任链、迭代结构中偶尔会有一点链表的影子,但是在工程里极少这么写,问题就在后期可能难以维护,出现问题也不好解决,简单来说就是中看不中用。

3.栈和队列、Hash与集合这几个绝对是应用开发的重点,我们会大量使用这几种工具。例如阻塞队列、HashMap等等。如果你研究JUC的源码,你会发现整个JUC是以AQS为基础,增加若干链表和辅助队列构建起来的,例如重入锁、Condition等等、而AQS本身也是一个双向循环队列。所以队列、Hash更多是在技术面试的过程中直接问你内部原理。

那会不会手写呢?很遗憾,几乎没有单纯考队列的问题,整个LeetCode里也没几道专门考察队列的问题。而Hash更多是算法的备胎,只要有更费脑细胞的算法,面试官就不会让你用Hash。为啥呢?一方面是因为很多题目一旦使用Hash就毫无含金量了,这就起不到考察思维能力的要求。另外就是本身需要开辟O(n)的空间,与那些中间只有O(1)相比就没有优势了。而在工作中,我们当然会选择简单、稳定、高效、易于维护的方式,大不了增加一下内存空间大小就行。这就看到了工程应用和面试算法的侧重点是不一样的。

对于栈,本身是有一些典型的题目的,例如括号匹配、计算器、表达式计算(例如逆波兰表达式)等等,但是请问工作中你遇到过几次这种问题?真遇到我们也会使用common、guava等库来辅助实现,不会自己亲自写。

4.再看树,请问你会在工程里写一个二叉树吗?真有一对多的关系,还是使用List多,因为二叉树扩展性太差了。而B*树、红黑树这些则是Mysql索引、HashMap源码等涉及的问题,本身还是挺复杂的,还是不会手写,算法真正喜欢考你的是二叉树的层次遍历、前序和后序遍历、中序遍历以及搜索树这几种场景。

5.图呢?几乎不会用,如果谁敢将结构设计成这样,十有八九是有问题的,因为你的代码用起来会有巨大的隐患。而在算法也很少考图,主要是因为构造图要么用邻接矩阵,要么用邻接表,代码都很多,再写算法就显得又臭又长,而图的广度优先、深度优先问题在二叉树遍历都有很好的体现。

6.查找和排序呢?遇到这种场景,我们一般也是直接调用Arrays或者List里的库函数,而不会自己写,为啥,世界高手已经将其维护几十年的算法绝对比你拍脑袋写出来的好,为了线上服务的稳定性,我们绝对倾向使用人家的。而在面试的时候呢?你就要硬着头皮写二分、写归并排序、写快速排序。

7.字符串的重要性不用说,工作中经常遇到,我们一般会使用很多工具库来减轻开发压力。位图的好处是占用空间小,计算效率高,所以在jvm、JUC、Spring、Dubbo等源码中大量使用,这个是我们研究源码一个非常重要的问题。而数字相对来说比较少一些。

从上面我们可以看到工作和面试对算法的要求是完全不一样的:

工作和面试对算法的要求对比
工作中 面试中
基本要求 稳定、高效、易维护 思维含量、执行效率如何
数组 使用List int[],int[][]
链表  几乎没有 考察大热门
队列 天天用,大量用 不会直接考,更多在广度优先等场景涉及
需要时使用库函数 没实际用处的问题:括号匹配、表达式等
Hash 天天用,能用就用 永远的备胎,能不用就不用
二叉树 几乎没有 面试属第一,永远炸子鸡
红黑树、B+树等 Mysql、HashMap等的根基 理解原理就行,一般不用写
不会用 极少遇到
查找、排序 调库函数 自己写

从图中我们可以看到,算法的重点是 数组、链表、二叉树、查找排序这些问题。这说明什么?说明如果你想靠工作经验来积累算法基本不可能,除非你技术足够好,面试官不考你算法,但是算法让然是不行的。

那链表等到底考什么东西,该怎么准备,脉络是什么呢?我们下一篇《算法的学习脉络》单独讨论。这里先看另外一个问题,数据结构和算法,以及初级算法和看似玄学的高级算法是什么关系呢?

对于数据结构和算法的关系,仁者见仁智者见智,我的理解是数据结构是载体,而算法是解决某类问题的思想。不管多么复杂的算法,最终都要落地到数组、二叉树等这种基本的结构上。而算法则会根据很多具体的问题抽象出一些思想,例如双指针、递归、分治、回溯、迭代、贪心、动态规划等等。

对于初级算法和高级算法的关系,同样仁者见仁智者见智,我的理解是基于数据结构的变形和拓展就属于初级算法。更难,针对场景更特殊的问题都属于高级算法,例如滑动窗口、回溯、贪心、动态规划等等,很明显后者是前者的延伸,前者是后者的基础。具体看这个表:

初级算法与高级算法的关系
初级算法 重要问题问题 高级算法
一维数组 增删时减少频繁移动,采取双指针策略 滑动窗口问题
二维数组 常见的花样就十来道题,会了就行了 高级算法的载体
链表 常见的花样就那么多,会了就行了 没有了
队栈Hash 常见的花样就那么多,会了就行了 单调栈、单调队列
常见的花样就那么多,会了就行了 前缀树、并查集
递归 有些问题用递归也写不出来 回溯
使用滚动数组等优化递归 动态规划的一部分
一些特殊的问题 贪心
数学与数字等等 数学问题等等

从上面这个简单的图可以看到两者有紧密的关系,回溯、动态规划、贪心、数学等等有大量的算法题,例如背包、子序列而研究这些问题的前提都是你对基础算法足够清楚。否则就会简单的不会,难的学不清楚,也就是简单的问题搞不清楚,就没资格学高级算法。在金庸武侠中,经常见到这样的场景,为什么同样的功夫有的越学越牛,有的就会走火入魔,甚至功力尽失,就是因为基础不牢,然后地动山摇。

那怎么才算把基础清楚了,什么情况下学习高级算法才有效果呢?初级和高级的边界在哪里?我找了几个题目,如果一题25分,看看你能得多少,至少75分才算合格吧。

纵横算法之三:算法到底考什么相关推荐

  1. CRC16算法之三:CRC16-CCITT-MODBUS算法的java实现

    CRC16算法系列文章: CRC16算法之一:CRC16-CCITT-FALSE算法的java实现 CRC16算法之二:CRC16-CCITT-XMODEM算法的java实现 CRC16算法之三:CR ...

  2. 算法的时间复杂度到底怎么算?

    算法的时间复杂度到底怎么算? 引言 假设计算机运行一行简单语句算作一次运算. def func1(num):print("Hello, World!\n") # 需要执行 1 次r ...

  3. 年薪20万、50万、100万的算法工程师,到底有什么区别?

    公元七世纪,在车迟国国家气象局组织的一次求雨活动中,虎力.鹿力.羊力三位大仙成功地祈下甘霖,于水火中救了黎民.老国王虽然不明就里,却从此尊他们为国师,奉道教为圭臬. 本世纪,算法工程师们的境遇也差不多 ...

  4. 【JVM进阶之路】垃圾回收机制和GC算法之三色标记(三)

    JVM往期文章 [JVM进阶之路]内存结构(一) [JVM进阶之路]玩转JVM中的对象(二) 上篇文章中讲到JVM中的对象以及判断对象的存活,那么对于"已死"的对象应该如何处理,怎 ...

  5. 最大流算法之三:ISAP

    最大流算法之三:ISAP <转> (2009-08-14 19:24:27) 转载▼ 标签: it 分类: 理论 通常的 SAP 类算法在寻找增广路时总要先进行 BFS,BFS 的最坏情况 ...

  6. 【广告算法工程师入门 6】【转】20万、50万、100万的算法工程师,到底有什么区别?

    需要了解一下广告算法工程师之间的区别,推荐这篇文章. [转]@北冥乘海生 ,想吸收更多负能量,请大家关注公众号"计算广告"(Comp_Ad)和知乎专栏"计算广告" ...

  7. 编程界称霸全球的10大算法,你到底了解几个呢?

    来源:课程图谱博客 本文约2300字,建议阅读9分钟 本文带你了解编程界称霸全球的十大算法. 算法究竟是什么? 简而言之,算法代表经过明确定义的计算过程,用于将输入转化为输出. 可以这样理解,算法是用 ...

  8. 程序员都会的五大算法之三(贪心算法),恶补恶补恶补!!!

    前言 点击查看算法介绍 五大算法 分治算法 动态规划 贪心算法 回溯算法 分支限界算法 WX搜素"Java长征记"对这些算法也有详细介绍. 贪心算法 一.算法概述 贪心算法也叫贪婪 ...

  9. 机器学习十大算法之三K-means

    K-means算法 (无监督算法,聚类算法) K-means算法,也称为K平均或K均值算法: K平均聚类的目的是:把n个点(可以是样本的一次观察或一个实例)划分到k个聚类中,使得每个点都属于离他最近中 ...

  10. 三大算法之三:贪心算法及其例题详解

    目录 零.前言 1.区分贪心算法和动态规划 1.动态规划 2.贪心算法 3.共通点 2.贪心算法得到最优解的条件 1.具有优化子结构 2.具有贪心选择性 3.任务安排问题 1.问题定义 2.优化子结构 ...

最新文章

  1. 用IKVMC将jar转成dll供c#调用
  2. python大神的成长之路_Python大神成长之路: 第二次学习记录
  3. CO葵花宝典-4.物料成本估算配置
  4. Pandas中文官档 ~ 基础用法1
  5. 判断 CGRect是否“为空”
  6. 博士毕业论文悲情致谢引女友回应:学术是一场超越金钱的修行
  7. 1G服务器网站,1核1g内存云服务器建网站
  8. 关于iOS声音识别的框架
  9. 数据库日志文件(databasename_log.ldf)太大 如何清除
  10. 哈工大车万翔教授:NLPer的核心竞争力是什么?
  11. Metasploit之——基本后渗透命令
  12. 关闭455端口相关服务
  13. 【信息系统项目管理师】第三章 立项管理思维导图
  14. 【SQLYOG】SSH ERROR:UNABLE TO OPEN CONNECTION:GETHOSTBYNAME:UNKNOWN ERROR牵引出来的一系列问题...
  15. CD光盘和电报的编码
  16. elementUI 表格合并单元格-多层级-合并行
  17. 携程、飞猪?大数据杀熟的背后,到底杀死了谁?
  18. C语言循环队列的基本操作(init,enquene,dequene)与杨辉三角(C和C++<queue>)
  19. 为什么单页面的seo不友好?如何解决这一问题?
  20. erdas2014安装

热门文章

  1. draco压缩引擎学习笔记(二)
  2. 台式计算机键盘灯打开方式,台式电脑开机时键盘灯不亮,必须要按一下Numlock才会亮,但系统没什么问题。怎么办?...
  3. SRAM与DRAM的区别
  4. DellR720安装系统不能正常进入系统
  5. 202109青少年软件编程(Python)等级考试(五级编程题)
  6. java wed 1
  7. python-转义字符及其使用
  8. 总结与归纳:深度神经网络中的数据融合方法
  9. 网络上行 下行速度测试软件,测试网络流畅度和上下行的方法
  10. 美国卡内基梅隆大学计算机排名,美国卡内基梅隆大学世界排名情况