算题感受和疑惑,望老师解答

来源:1-5 大厂面试为什么总考算法?

Potter520

2022-08-20

  • 第1阶段:
    对一个题目没啥感觉,可能知道怎么解就可以解出来,不知道解就完全无思路(完全的新手)
    解决办法:通过系统的学习老师的课程【算法与数据结构】
  • 第2阶段:
    虽然学完 【算法与数据结构】课程,刚开始刷题是一股脑子的从第一题开始刷,结果刷到最后放弃
    总结问题:无策略、无脑式的刷经常碰到一个问题要卡很久,搞了很多次之后就放弃了
  • 第3阶段:
    通过了解别人是如何刷题的,意识到刷题是有讲究的,不是一股脑从头开始刷,而是要针对一个知识点来针对性的刷题,巩固对一个知识点的理解,立马就买了老师的这个【实战 / 玩转算法面试-- Leetcode真题分门别类讲解】课程,一直坚持到现在3个多月了,刷了164道题。(感谢老师的课程,让我成长很多,让我对算法不那么害怕了)
    我的思路是:按照老师给的知识点对应的题型刷,把每一个知识点都巩固得牢一点。等到面试的时候再刷easy题和medium(面试的时候不考hard题,时间太短也搞不出来。重点刷easy题)找感觉,随机测试自己。
    在目前这个阶段,我有一个疑惑就是,老师给出来有的题目确实有难度(medium,hard),之前是完全无思路,现在是我有点思路但是有不是那么清晰,我硬刚也能搞出来,比如:37.解数独,但是提交后的通过效果不太好,超过15%(当然可以想办法优化),面对我目前的这种情况,我要继续硬刚解题么?假如老师也面对这种情况,想知道老师是如何思考的,以及是如何应对的?
写回答

1回答

liuyubobobo

2022-08-25

随便聊两句。


首先,其实我在我的【算法与数据结构体系课程】的第一章应该强调过:我的体系结构的课程并不是一个刷题课。所以,上那个课程并不能让你在 Leetcode 上见一道题会一道题。这点很重要。我生怕很多同学学习我的那个课程的目的就是希望在 Leetcode 上“所向无敌”,所以特意强调过。也可以参考我的这个问答:https://class.imooc.com/course/qadetail/331667


但是,我近乎可以很肯定地说,对于计算机专业的大多数工程师来讲,我的算法体系课成中的一个个算法和数据结构的原理,是重要的;而 Leetcode 上的大多数题目,其实是不重要的。学习好那些算法和数据结构的基础原理,在后续学习近乎任何计算机的其他领域的时候,都用得到;但是,Leetcode 中很多题目,真的只是“题目”而已。当然,不能说一点作用没有,尤其是抽象地说,作为思维训练,还是很有用的,但是,他们的直接作用,并没有那么大,最大的直接作用,就是面试而已。


==========


对于刷题,是的,不是按照题号刷,而应该按照“主题”刷。可以参考我的这篇文章:https://www.imooc.com/article/317697


==========


整体,我个人认为,准备面试或者笔试的算法问题,难度选择上应该以 medium 为主,而非 easy,也不是 hard。

整体来讲,Leetcode 上近乎所有的 easy 的问题,不管描述多复杂,都近乎一定可以“暴力”解决。所以是 easy。medium 的问题整体光谱更宽,使用的算法,数据结构,或者技巧更加“常见”且“有代表意义”一些。


不过,其实 Leetcode 上问题的难度标签是很粗糙的。这里有几方面原因:


一方面原因是,随着时代的推进,在以前看来一些比较“复杂”的问题,如今已经“人尽皆知”,所以并不能称为 hard 了。所以在 Leetcode 上你会看到类似的情况,一个“比较早”的 hard 的问题,可能和一个近期的 medium 问题难度相当,甚至比 medium 的问题还简单;


另一方面,把问题只分成 简单,中等,难,其实有些粗糙了。大多数竞赛网站的难度都不是这样做的,而是使用一个难度系数,所以精度会更高一些。在 Leetcode 上,你看一道 medium 的问题,觉得很简单,看另一个 medium 的问题,却觉得一点儿思路都没有,这是很正常的,因为一个问题是 medium 的问题里偏简单的;另一个问题是 medium 里偏难的;甚至你看一个 hard 问题觉得很简单,另一个 hard 问题一点儿思路都没有,都是正常的。


(我听有的同学和我反应过,Leetcode 已经将一批过去的 hard 问题“降至” medium 难度了,对次我没有关注。但是不管怎样,只用三个难度等级去衡量 2000 + 的问题,确实粗糙了。)


所以,你在刷题的过程中,遇到 medium 的问题没有思路,也不用沮丧。简单来说,把 Leetcode 当做学习网站而非刷题网站,可能心态会更好。遇到不会的问题,看题解,看别人怎么解决,去学习,你就进步了,有经验了,下次简单类似的思路,就有方向了;而不要看到一个问题不会,就觉得自己实力不够,望而却步。


另外,Leetcode 上的一些问题使用的“技巧”,在我看来真的不具有代表性,但是很多同学看到这类问题,觉得自己不会,又会心慌。对此我非常理解。我建议参考一下我的这个问答(在图论课程中):https://coding.imooc.com/learn/questiondetail/vQW1lYEpapjPyE9A.html


==========


Leetcode 上的 时间超过百分之多少,这个指标意义不大。这是因为,Leetcode 的很多问题,后来添加了更多的测试用例,这就会导致后来提交的代码,需要运转更多的测试用例,其消耗的时间,肯定会超过最初提交的代码。更不用提还有运行环境的变化。


我个人认可的一个简单的原则是,做完一个问题,如果你觉得你的代码不够“好”,那么就去看看题解,看看别人的思路和代码。你最应该关注的,是复杂度级别的优化。如果你用 O(n^2) 解决了这个问题,但其实这个问题有 O(nlogn) 的解决方式,或者有 O(n) 的解决方式,那么就可以稍微学习一下,是如何做到这种复杂度的优化的。


但是,也并不是所有的“复杂度级别的优化”都是值得学习的。因为有一些算法的优化,实在太“冷门”了,说实话,对于 99% 的程序员来说,这辈子用到的概率为 0,甚至从应试的角度,遇到的概率也为 0,根本没有必要学习。比如 5 号问题的 Mancher 算法(中文世界中有很多人叫马拉车算法...)。说实话,这个算法你在 99% 的算法教材中都根本看不到。这种算法就是太偏门了,没有必要掌握。


怎么鉴别一个算法是不是“偏门”?可以参考这里:https://coding.imooc.com/learn/questiondetail/vQW1lYEpapjPyE9A.html


至于复杂度相同,但是实现细节不同,导致的性能差距,也要具体问题具体分析了。有一些实现是值得学习的,但又一些不值得学习。这种情况就看你心情了。你可能翻题解的时候,看到有一个代码,算法思路和你相同,但实现的代码行数比你少一半,你要是愿意,可以研究一下他的实现是怎样的。但如果心情不好,不研究我觉得没毛病。


我可以告诉你的我上学的时候,准备算法竞赛的整体策略。整体就是:做出来 大于 优雅的做出来。就是这么简单。


一个问题,首先要想办法把他正确的解决。如果能正确的解决,我又觉得自己的思路挺清晰,我不会去纠结更多别的。因为自己不会的东西太多了,没必要为一个已经能解决的问题纠结太久,不如把更多的时间花在去学习心得知识,攻克新的问题上。


这其实也是我一直强调的:不要完美主义。“完成”大于“完美”。当然,在具体实践上,怎么就叫“完成”,怎么就叫“完美”,每个人的标准也不同,大家可以视自己的具体情况具体问题具体分析。但是大的原则应该是这样的。


个人建议,仅供参考。继续加油!:)



0
1
Potter520
多谢老师的指点
2022-08-25
共1条回复

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程