ARTS 第 54 周

题图:Photo by Photo by Graham Holtshausen on Unsplash

每周完成一个 ARTS:
Algorithm: 每周至少做一个 LeetCode 的算法题
Review: 阅读并点评至少一篇英文技术文章
Tips: 学习至少一个技术技巧
Share: 分享一篇有观点和思考的技术文章

题图:Photo by Graham Holtshausen on Unsplash

Contents

Algorithm

226. Invert Binary Tree

题目:226. Invert Binary Tree

难度:Easy

题意:Invert a binary tree.

示例:

Input:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

Output:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

Trivia:

This problem was inspired by this original tweet by Max Howell:

Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so f*** off.

琐事:

这道题其实非常有意思,Homebrew 这款软件是 Mac 上非常强大的一款包管理器,用过 Mac 的程序员们 100% 都用过它,能写出这么强大的软件的作者,其编程功力肯定不低。但作者 Max Howell 去面试谷歌时,却在白板编码的时候被这道反转二叉树的题目难住了,最后被谷歌拒绝。于是 Max 回到家就发了这条推特 diss 谷歌。

解法:

这道题的解法其实也挺简单的,思路还是先自上而下后自下而上的递归。

代码:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if root is not None:
            root.left, root.right = self.invertTree(root.right), self.invertTree(root.left)
        return root

时空复杂度都是 $O(n)$。

Review

How to Write a Thesis

本周阅读了 MIT Press 上的一篇文章《How to Write a Thesis》。

这篇文章其实是从作者 Umberto Eco 的书《How to Write a Thesis》中截取的一篇,但其中已经提到了不少写论文需要注意的地方。我抽几个来说说:

  1. 你不是普鲁斯特,不要写长句子

    不要写长句子,不要害怕把一个主语说两遍,不要用太多的代词和无聊的从句。

  2. 经常性地另起一段

    逻辑上需要的时候,或者是文章的节奏需要的时候,另起一段,并且越多越好。

  3. 把任何涌进你脑袋中的东西写下来,但只在初稿中写

    这样可以帮助你记录下自己的灵感,之后你可以把这些思考都放进附录中。

  4. 把你的导师想象成几内亚猪

    在你还远没有完成你的论文的时候,就应该把论文的至少第一章拿给你的导师看,TA 的建议会对你非常有用。

  5. 不要坚持从第一章开始

    如果第四章的工作是你的重点,那么就从它开始吧,假装别人已经为你写好了之前的几个章节。目录会帮助你的。

  6. 不要用省略号和感叹号,也不要解释任何的比喻

    要么不要使用比喻,要么使用了就不要解释它,否则你就是把读者当成了一个傻子,而读者通常也会这么反击的。

  7. 在你引入一个东西之前,定义它

    如果你不知道这个东西的定义,那就不要用它。如果它是你论文的重要主题之一,而你还不知道如何对它下定义,那证明你选了一个错误的题目。

文章中有非常多的例子,但因为作者是小说家和文学评论家,所以举的例子大都是文学和修辞方面的,而且有很多很多高级词汇,导致有些例子我也不太能看懂,但就其中我提到的这几个点已经足以让我受益匪浅。感兴趣的或者觉得自己论文的质量需要提高的可以一读。

Tips

VS Code 里一些常用的快捷键

这周给大家介绍一些 VS Code 中我常用的快捷键吧,你可能不会知道哟!

  1. 横向拆分编辑器——Cmd+\

    拆分编辑器可以说是大多数编辑器都支持的操作了,没什么好说的,你可以横向拆分很多个编辑窗口,每个编辑窗口被称作一个编辑器组(Editor Group)

    横向拆分

  2. 将横向拆分的窗口纵向显示——Option+Cmd+0

    如题所示,如果你需要把横向拆分的编辑窗口纵向排布,可以按下 Option+Cmd+0 来实现。

    纵向拆分

  3. 在不同的编辑器组之间跳转——Cmd+1、Cmd+2……

  4. 在同一个编辑器组的不同 Tap 之间跳转——Ctrl+1、Ctrl+2……

  5. 网格布局

    使用 Grid Editor Layout (2x2) 这个命令来实现如下效果:

    2x2

    你也可以通过拖拽边界来实现不同窗口大小的切分。

  6. 在不同编辑窗口中跳转

    使用 Cmd+k+↑、Cmd+k+↓、Cmd+k+←、Cmd+k+→ 来在不同编辑窗口(组)中跳转。

  7. 关闭侧边栏——Cmd+B

  8. 切换居中布局

    关闭侧边栏之后,我们所有的代码就会全部堆到左上角,这个时候怎么办呢?

    Non Centered Layout

    可以试试运行 Toggle Centered Layout 这个命令,来将当前的这个编辑窗口居中显示。

    Center Layout

    拖动两边的边框还可以调整宽度。

  9. 禅模式——Cmd+K+Z

    按下这个快捷键之后,侧边栏、状态栏和面板都会被隐藏了:

    Zen Mode

使用快捷键可以提升不少编程的效率,当然快捷键的使用和编辑器的配置,完全看个人需求和喜好,只要得心应手就好(比如我现在就把 VS Code 中的 Vim 插件卸载了,因为 Vim 对于中文编写实在不友好😩)。

Share

关于学习编程和调用函数的一个形象的比喻

Greg Snow 在 2006 年 5 月 的 R help mailing list 中对数据科学家在学习 R 语言编程和调用 SPSS 内置函数的选择之间给出了一个形象的比喻,原文如下:

Busses are very easy to use, you just need to know which bus to get on, where to get on, and where to get off (and you need to pay your fare). Cars, on the other hand, require much more work: you need to have some type of map or directions (even if the map is in your head), you need to put gas in every now and then, you need to know the rules of the road (have some type of drivers license). The big advantage of the car is that it can take you a bunch of places that the bus does not go and it is quicker for some trips that would require transferring between busses. Using this analogy, programs like SPSS are busses, easy to use for the standard things, but very frustrating if you want to do something that is not already preprogrammed. R is a 4-wheel drive SUV (though environmentally friendly) with a bike on the back, a kayak on top, good walking and running shoes in the passenger seat, and mountain climbing and spelunking gear in the back. R can take you anywhere you want to go if you take time to learn how to use the equipment, but that is going to take longer than learning where the bus stops are in SPSS.

大意是调用函数就像乘坐公共汽车,你只要知道「乘坐哪辆公交」、「从哪站上车」以及「从哪站下车」就可以了。而学习编程就像开自己的车,需要更多的工作:你需要有一张地图(脑袋中有也算),你需要时不时地给车加油,你需要知晓道路和交通规则(持有驾照)。但开自己的车的好处是,自己的车可以带你去到更多更多公共汽车去不了的地方,不需要换乘,且更快。

接下来这个比喻对比了 SPSS 和 R。SPSS 就像公共汽车,对标准的问题十分易用,但如果你想做一些其他没有被预编程的事情,就很困难了。而 R 就是一辆四驱 SUV,后座上放着一辆自行车,顶上架着一艘小船,乘客座位上有舒适的跑鞋,后备箱里还有登山和洞穴探险的装备。

R 会带你去任何你想要去的地方,只要你愿意花时间学习如何使用哪些装备,只是这会比学习 SPSS 这辆公交车在哪里停要更花时间。

这个比喻太形象了,而且易懂。如果只是简单地学习如何调包,那你的很多行为想法都会受到限制,尤其是像 R 和 MATLAB 这类有非常多内置函数的语言,如果你不了解如何正确地使用这些语言编程,那么就和用了一个高级版的 Excel 差不多,它只是一辆公共汽车,只能把你带到一些特定的地方。

对数据科学家而言,灵活使用一种编程语言来解决问题非常重要。根据问题的不同,同一种方法会有不同的细节,而不同的问题也有着不同的解决方案。如果你不能为你的问题量身打造一个方案,你可能就会尝试构建一些并不现实的假设,从而使用一些已经存在但并不适用的方法,这样并不能解决问题。

WeChat QRCode