斯坦福算法Specialization的收获

为什么要写这篇文章

从5月份开始,我加入了Coursera上的“斯坦福算法Specialization”, 到现在已经完成了两门课,收获颇为丰富。今天想到一个道理:学习是要有产出的,我回顾了一下这几个月的学习历程,程序写得不少,笔记也记了一叠又一叠,总结性的文章却没有怎么写。这篇博文就是要fill this gap, 我到底学到了什么,这些东西有用在哪里,总结就是为了给自己一个清楚的概念,让我能够很快地回答这些问题。

同时写作也是一个爱好。看到博客上文章的阅读量攀升,我是能够感觉到很强烈的成就感,虽然至今没有评论,但那些真实的阅读量给我一种intuition which is like “我写的东西有人看,这挺好的”。废话少说,我们进入正题。

收获一:建立起与Graph的舒适感

用英文讲就是 Now I can feel more comfortable working with graph. 最早接触图论的时候总觉得它是个高不可攀的东西,各种概念种类繁多;图这个东西不仅有结点,还有边,边还能有向和无向,方向之外它还可以有权重…. 总之对初学者来说,这么多概念砸在一起确实让人挺无奈。大学里学了离散数学,对图论已经有所了解,现在再学起跟图有关的算法,其实是把高中那些overwhelming的知识点重学一遍,自然是感觉舒服得多。

我的Primary Language是Java,现在碰到用得到图的问题,我会很熟练地去使用JGraphT这个API. 在pom.xml 里加上一些dependency信息就能够很好地调用,这是一个挺好的库,跟图有关的操作比如 getEdge(Vertex v1, Vertex v2), getEdgeWeight 还有一些获取结点neighbor的方法都非常实用,免去了自己实现的烦躁。最近实习的项目里需要管理一些dependency, 有些依赖是双向的,有些是单向的,我很自然地就用graph作为数据结构,PM需要app能够取出所有的dependencies 可以用获取结点所有neighbor的方法解决。

我自己的图论词汇量也获得了拓展。Dijkstra 这个词我一直觉得可怕,一方面觉得它的算法难以理解,另一方面我始终不知道怎么念这个名字。这两方面都是问题,但我都找到解决的办法了。如果对图的基本概念熟悉以后,研究一下Dijkstra Shortest Path的伪代码就会发现这是一个非常容易理解的算法,实际上所有好的算法都share this property of simplicity. 我又自己实现了一下,算法在一个很大的data set上运算正确,第一个问题就算我解决完毕。第二个问题其实更简单,视频课里面斯坦福的老师一遍又一遍重复他的名字,我不想知道也要知道了他的读音,j k 都不发音,念它的时候可以把两个字母省略掉… period.

收获二:更深入理解了Big-Oh Notation

Big-Oh Notation 就是O( n ), O( logn )这种记号,多用在算法时间复杂度分析中。这个记号其实不陌生,数学分析里用它来表示两个无穷小谁更小,但是在算法分析里我始终没能够系统地学习它。这个Specialization里,Big-Oh Notation变成了刚需。几乎每一个算法都会经历分析的步骤。

Big-Oh Notation 是算法速度的度量衡。主讲人Tim Roughgarden说过一句话,每一个算法设计者都要经常问自己一个问题:can we do better? 也就是说你设计出了一个算法,解决了一个问题,你需要相信那里总有一个优化的可能性,你可以让程序跑得更快。怎样算快?一种naive的想法就是计时,同一份data set看哪个算法消耗的时间短,但这种方法是data-dependent的,它一来不能够反应在数据规模改变的时候算法的优劣,而且data set的偶然性也会导致它成为一种不太可信的方法。所以我们要使用Big-Oh Notation作为算法分析的度量衡,它反应了算法消耗的时间随数据规模的变化情况,最理想的情况是linear time cost, 也就是 O(n) 的时间复杂度。

收获三:有了深入学习数据结构的方法论

学习要挑重点,然而挑重点本身就是一种能力。我一般学习新事物的时候会更关注那些我熟悉的方面,在这些方面多研究和拓展,积累知识和自信,进而再加深对big picture的了解。本质就是三个步骤:
1. 找到熟悉的方面/知识点
2. 从这方面着手,多研究
3. 以已经学到的知识作为基础,建立起对大局的概念
这三个方面都是time and energy consuming的,本段开头讲到的挑重点的能力就是第一个方面。

通过这个Specialization 的学习,我懂得了在数据结构的学习方面如何找重点。面对一个新的数据结构,你需要了解两个方面,第一是它支持什么Operation, 第二是对于这些opeartion,该数据结构支持怎样的Running Time.

用这个方法我学习了heap这种数据结构,它主要支持两种Operation. 一个是insert, 另一个就是extract-min, 挑出最小的数,两个操作的时间复杂度都是 O(logn) . 所以如果你的应用经常要从一个数据结构里挑最小的数,可以考虑使用heap.

收获四:学到了英文数理证明的基本词汇

几个月的学习以来,跟着老师证明了很多定理,这些定理都是用英文陈述,英文证明的,一开始有些吃力,慢慢就熟悉了其中的逻辑,不得不说英文作为一个逻辑性很强的语言,用它书写的证明逻辑也是非常清晰和可读的。

总结

以上就是我在学习斯坦福算法Specialization中获得的一些心得,其实还有很多是埋在水里的,写出来的只能是冰山一角。当然,既然能写出来,说明在这些方面我确实理解得很好。我很感激Tim Roughgarden,他为我们提供了非常好的一套课程,每个月$35的价格也是比较良心的,我非常推荐大家去学一学。

你可能感兴趣的:(算法,数据结构,复习)