(笔记)如何快速攻破传统算法和数据结构

知乎上的SimonS大神的讲座,给想学习算法的童鞋的一些建议:

https://www.zhihu.com/lives/795264798257479680


一,QA部分:


1. 985 大二 专业软工 没有oi经历。如何一年时间拿到ACM区预赛银牌?
主要参考后续的live,实际是有可能的。只需要选择对的方法


2. 如何高效刷算法题(算法面试题)呢?坚持不看答案要卡很久,效率低。
可是看过答案又记不住,下次遇到接着卡壳,如此反复好受打击
主要做到训练以后能举一反三。


3. 接着作者举了一道面试的算法题(字符串chain)?
后续研究看看(属于LeetCode中等难度)




答案是一个DP的解
live主贴出了一道python的解法



4. 老师你好,我现在大二软件专业,对算法的学习有点力不从心
静不下心来,感觉这也很难那也很难,那种焦躁的心情怎么解决?
是不是算法不适合我?
live主认为提问者现在处于浮躁的状态,很难静下心。
leetcode比竞赛简单,属于编程入门(不算竞赛入门)
leetcode中等偏上属于算法入门。


5. 数据结构怎么学,是否按照书本来打代码?
不推荐书本打代码。
需要一个能检验你代码正确性的平台。一个oj,leetcode等。


6. 普通二本生有必要入acm坑?
无论学校背景,甚至职校学生都推荐参加ACM。


7. 大二ACMer,用一年时间来训练,如何训练好?一些基本的算法都有了解。
还有大一新生,应该怎样给他们安排训练计划?没有算法基础
先组三人队伍,多参加线上比赛。
大一新生,多做内部个人比赛。


7. 大二ACMer,用一年时间来训练,如何训练好?一些基本的算法都有了解。
还有大一新生,应该怎样给他们安排训练计划?没有算法基础
先组三人队伍,多参加线上比赛。
大一新生,多做内部个人比赛。


8. 如何比较好等准备机器学习算法等基础模型?
多掌握统计学等基础 特征工程


9, 学习算法,是不是数学知识要求很高呢? 需要哪方面等知识铺垫?
传统算法对数学知识要求并不算太高。(线性代数,初等数论竞赛用)
但是算法分析方面对数学要求会高一个层次。
(线性代数,离散数学,初等数论,组合数学等等)
机器学习要求数学更高(线性代数和统计学,微积分)


10. 图像识别算法怎么入门比较好,工程应用?
模式识别


11. 怎么学数据结构才是比较好的方法,老师都是让我们照着课本打代码,
这样感觉跟背公式应付考试一样。
首先需要对知识体系有一个系统的了解,接着再针对性的做题目。


12. 写某些高级数据结构容易写炸,要花半天功夫去调试,怎么办呢?
设计测试,写一块测一块。
增加一个模块,就测试一块保证起正常。


13. 本科生参加竞赛和刷leetcode,如果遇到自己想很久都想不出来的问题是否应该
直接看答案?
Leetcode 有不少提示,如果提示看不懂参考Discuss(不看Show代码)


14. 机器学习方法,学习数据结构通过国内互联网公司笔试,编程语言
选择python还是c++?
live主两者都要学python和c++, 甚至还需要学java
难点在于机器学习的核心思想,统计学等


15. ACM选手如何系统学习复杂的算法和数据结构?
复杂每个人定义不一样。
例如:树形动态规划,解决哪一类问题?去哪里解决这一类问题(做题)
反思总结


16. 请问计算广告的后端工程师需要掌握像算法工程师一样的机器学习
的相关算法来提高核心竞争力吗?
live主认为没必要。
后端工程师的未来是-》系统架构师,优化,并发量。
机器学习算法-》全栈工程师-》抢饭碗?


17. 算法导论这本书如何高效使用呢?
不建议入门使用。在自认为掌握扎实了再去学习。


18. 如何刷Leetcode和机器学习算法?
1)按题目序号
2)按题目从简单到难
3)按随机
因人而异
对机器学习的基础,特征工程。


19.在完全没有算法基础,仅有一点c语言基础上,
有没有学习算法列表(由浅入深这种),
如何才能掌握一个算法呢?
leetcode由easy - medium - hard
一个算法大纲:
https://www.zhihu.com/question/23148377/answer/36824071


20.普通应用开发工程师,比如前端开发,移动开发,需要对数据结构和算法
学习多少?需要花时间学习么。如何平衡学应用的时间和学算法的时间?
前端不是有必要去学习算法。
如果感兴趣每天做1~2题Leetcode就足够。


21.底层算法C++工程师,偏图像处理方向,如何入门相关算法?
模式识别相关。


22.Coursera还是直接看书好?
最高效的学习方法是做题。
了解框架概念,做题。




23.数据结构公开课,练习题?
MIT的官方课程:
Introduction to Algorithm
Advance data structure
练习就刷leetcode,poj可以了。




24.机器学习该如何入门?
普通程序员如何像人工智能靠拢
https://www.zhihu.com/question/51039416/answer/134564100




25.为什么面试中DP(动态规划)比较多?
除了DP其他都可以套模版来解决。




26.如何寻找算法的资料?比如0基础,贪心,
分治,回溯这些?比如我在做一道题以后,我想对
这个算法了解更多的情况。
专题训练,后期看权威著作。如算导




27.在oj上刷题,遇到不会的要如何处理?应该花多少时间
去看题解,看了题解以后怎么办?如何防治下一次遇到同样的
还不会呢?
看完答案,手动实现一遍。对同类题做专项训练


29.徒手写算法代码的能力重要么?有什么用?
白板编程。看出对编程语言的熟练程度,
第一时间想到埋下的坑。边界条件。


30.cpp和java写算法容易忘记,python不容易忘记。
因为python更像自然语言。c++要考虑更多问题。


31.一个学习大纲
live主推荐的一个给算法,系统工程师等的学习大纲:
https://zhuanlan.zhihu.com/p/22543073


二,正文大纲



如何快速攻破传统算法和数据结构
算法工程师内功篇(一)


*为什么面试官都喜欢考察程序员基础算法?
*如何高效,系统性地学习算法和数据结构?
*为什么大家普遍觉得动态规划较难理解?
*学算法是否有必要参加OI/ACM等算法编程?
*如何平衡自己在算法竞赛和其他方面的精力?
*学习传统算法对日后工作的帮助具体有多大?
*学习传统算法对机器学习的帮助具体有多大?
*面经分享


1)为什么面试官都喜欢考察程序员基础算法?

*面试者工龄在3年以内尤甚


*考察底子是否扎实,即使该知识点可能用不上
例如缓存管理LRU算法。造轮子
计算广告中,查找手机IMEI集合(数据大)


*考察是否聪明,能否在短时间提供解决方案
例如动态规划(前面的字符串相识的问题,计算编辑举例,自动机)


*避免产生时间复杂度上的常识性灾难
例如滥用MAP容器。


2)如何高效,系统性地学习算法和数据结构?

*先系统后高效
*何为系统性学习?
    * 全面(均有涉猎但不必深究)
    例如Map容器,红黑树,实现方式,特性等等。一种对平衡树无法解决问题的拓展
    * 应用(自己手动编写)
    例如对平衡树的特性有过了解,自己手动实现过平衡树的几种实现和变种。
    * 思考(加深理解,举一反三)
    知道平衡树的多种实现,思考对比多种实现的优缺点和关系,如何进一步优化呢?
    能更深入理解你对知识点的理解

作者认为如果是一个985/211等学生半年时间从0开始补算法是可以达到一个省赛金牌的水平

* 如何高效做到系统性学习?
    * 全面(找一份学习大纲,可以参考live主在知乎上的回答)
    作为一个技能树的标准
    https://www.zhihu.com/question2/3148377/answer/36824017
    * 应用(找题库,LeetCode/POJ/ZOJ等,还有USACO, URAL)
    * 思考(取若干道同类型的boss题,独立完成)
    举例:学习了dynamic Programming 。然后去leetcode上把dynamic programming标签
    等题目都做了。
    * 再思考(阅读《算法导论》等著作)也叫深入思考
    live主认为,应系统学习过一遍常规经典算法以后再去看算法导论,
    系统性深入了解补充自己欠缺的地方。


* 针对竞赛
    * 动手实践远比看书重要
    live主认为多写代码比多看书更重要。(针对竞赛)


    * 不要在自己觉得过难的知识点上死磕
    例如觉得DP已经有一定深度了,但是不应该在DP上钻牛角尖,因为还有大量数据结构需要学习


    * 要用自己擅长的方向(DP,数论,图论,计算几何,数据结构)
    因为ACM是3人组合,每个人需要有自己的擅长方向。类比Dota游戏,每个英雄要有自己的发展方向。
    法系英雄不要补物理装,而物理英雄不要出法系装备一样!
    live当年参加ACM的时候,主攻DP和初等数论, 队友攻计算几何和数据结构,另外一个队友思考Trickle
    在有限的训练时间内,让整个团队的实力得到一个最大化的提升。


    * 每次解题都要计时和统计提交次数
    给自己一个压迫感,给自己比赛有一个氛围。
    装平时训练中要有掐时间的习惯。才能在比赛中做到有条不紊。


3)为什么大家普遍觉得动态规划较难理解?

参考


(不知道为啥,我觉得这个是统计学中计算数学期望的题目呢?)
如果偷两件银行1,2风险是:
风险计算  1 - (1 - R1)* (1 - R2)


动态规划和记忆化搜索的区别?
DP应用了记忆画搜索的思路。




暴力枚举:N家银行选或不选,O(2^N)的时间复杂度,不可取
思考子状态:
    * 枚举计算只抢前i家银行的最大金额?不能,有后效性,要增加纬度
    * 枚举每个概率下的最大抢劫金额?太麻烦,可能有精度灾难
    * 枚举每个抢的金额下最大逃脱概率?可行,轻松解决
状态:F[i], 表示抢i块钱的最大逃脱概率
初始化:F[0] = 1, 其余为 -1(抢0块钱肯定100%逃脱)
转移方程:F[i] = max{f[i], f[i-Mj]*(1-Rj)}
时间复杂度:金额最大是10000, 所以是O(kN)


*目标:求解决策过程最优化的数学方法
*步骤:
    * 寻找子问题(最优子结构)
    * 确定状态(时空复杂度)
    * 确保没有后效性
    * 寻找转移关系及合适的枚举方向
    * Coding!


4)学算法是否有必要参加OI/ACM等算法编程竞赛?

OI:无论从功利目的还是兴趣出发,除非你有很好的环境和很大的自信
并且有丰富的闲余时间,否则均不建议参加
    * 初高中学业压力大,OI不能作为主要学业
    * NOIP已经没有了保送一流名校的资格
    * 为未来选择一个好的竞赛氛围和好队友更重要


ACM:无论你在算法方面是否有所建树,都建议参加
    * 感受比OI更激烈的竞赛氛围
    * 增加团队高效沟通合作的技能点
    * 未来就业的金牌敲门砖


5)如何平衡自己在算法竞赛上和其他方面的精力投入?
参考图




6)学习传统算法对日后工作的帮助具体有多大?

* 基础扎实,Coding速度和质量都有极高的保证
    * 中间件开发,可快速胜任造轮子的岗位
    * 极大降低加班时间,提升程序员生活幸福感


* 解决问题能力强,拥有较高的计算机思维
    * 擅长用树,图等非线性数据结构将问题抽象化
    * 擅长计算时间空间复杂度,保证公司资源的最大化利用
--
* 场景:2016年淘宝双11有10.5亿笔交易,假设拥有这些交易的日志文件,
如何快速统计出当天销量最高的100件商品?


* 简化问题,在不考虑内存瓶颈大情况下,用Hash统计每件商品的成交量,
并同时利用最小堆维护当前销量最高大100件商品。遍历完所有日志后,堆中存储
着的即是答案。算法达O(kN)时间线性复杂度。


7)学习传统算法对学习机器学习的帮助具体有多大?

* 许多性能优化方向(线性代数相关尤甚)
* 可以在多项式时间内寻找最优解
图论在计算广告中的应用
https://zhuanlan.zhihu.com/p/23562855


8)面经分享

* 在一列无序数列中寻找中位数
暴力:排序取中间点nlogn
快排分治思想:partition之后丢掉一部分。 线性复杂度
* 给出10万条人和人之间的朋友关系,求出这些人中有多少个朋友圈
无向图,求多少孤立岛。连通分量
暴力:DFS,BFS搜索。
并查集
* 在一个很长的二进制串中,求除以3的余数
正规做法:自动机。递推关系
* 在一个需要频繁更新的业务场景下,求出区间和
线段树,区间树(签到题)
* 在一个原本应该成对出现的数列中,寻找唯一一个不成对的数
比如2个2,2个4.
位运算异或


最后我发现《数据结构与算法分析C/C++语言描述》这本书算是比较全面性介绍了算法根据大纲来(也叫小算法导论 因为这本书涵盖的范围最广泛),

虽然《算法4》推荐的人热度更高,但是《算法4》介绍的算法并不算全面,可以作为补充材料阅读。

清华大学的那套《数据结构C++》也属于这种情况,虽然每个章节都有一定深度的展开,资料也足够详细但是像动态规划这样的都没有介绍到。

暂定以《数据结构与算法分析C++语言描述》为主要学习课本,算法4(有介绍字符串距离,正则表达式)的部分可以进行阅读

《数据结构C++》里甚至有哈夫曼树和红黑树的实现,深度也足够。可以进行扩展性阅读。

最后再考虑阅读《算法导论》

没有更多推荐了,返回首页