ARTS 第 33 周

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


Contents


Algorithm

70. Climbing stairs

题目:70. Climbing stairs

难度:Easy

题意:

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Note: Given n will be a positive integer.

示例 1:

Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

示例 2:

Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

解法:

题干中给出跨台阶有两种方法,一种是一步一级台阶,一种是一步两级台阶。假设我到达第 n 级台阶的方式有 F(n) 种,我有两种可能性,第一种是从第 n-1 级台阶跨了一级上来的,到达第 n-1 级台阶有 F(n-1) 种可能性,第二种是从第 n-2 级台阶跨了两级上来的,到达第 n-2 级台阶有 F(n-2) 种可能性,那么 F(n) = F(n-1) + F(n-2)。这么一看是不是就很清楚了?很明显的斐波那契数列嘛,那么现在写出几种方法。

方法 1:

根据斐波那契数列的性质,直接计算第 n 级台阶的可能性。

代码:

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 1: return 1

        first, second = 1, 2
        for _ in range(3, n+1):
            first, second = second, first + second
        return second

时间复杂度 O(N),空间复杂度 O(1)。

方法 2:

根据斐波那契数列的通项,直接给出答案。

计算斐波那契数列通项的方法如下:我们有 $F_0 = 1, F_1 = 1, F_n = F_{n-1} + F_{n-2}$,假设 $F_n = x^n$,那么我们有 $F_{n-1} = x^{n-1}, F_{n-2} = x^{n-2}$,那么 $x^n = x^{n-1} + x^{n-2}$。取 $n = 2$,有 $x^2 = x + 1$,解方程得 $x = \frac{1\pm\sqrt{5}}{2}$。

于是 $F_n = A(\frac{1+\sqrt{5}}{2})^n + B(\frac{1-\sqrt{5}}{2})^n$,将 $F_0 = 1, F_1 = 1$ 代入,解得 $A = \frac{1+\sqrt{5}}{2\sqrt{5}}, B = -\frac{1-\sqrt{5}}{2\sqrt{5}}$。于是 $F_n = \frac{(\frac{1+\sqrt{5}}{2})^{n+1} - (\frac{1-\sqrt{5}}{2})^{n+1}}{\sqrt{5}}$。

代码:

class Solution:
    def climbStairs(self, n: int) -> int:
       from math import sqrt
       return int((((1+sqrt(5))/2)**(n+1) - ((1-sqrt(5))/2)**(n+1))/(sqrt(5)))

时间复杂度 O(log n)(因为 python 的 **pow() 是 log 时间复杂度,而 math.pow() 因为支持浮点运算,牺牲了一些精度,所以是常数时间复杂度 O(1),具体可以查看这个链接),空间复杂度 O(1)。


Review

Bartek’s coding blog: C++ Ecosystem: Compilers, IDEs, Tools, Testing and More

本周阅读了这篇讲述 C++ 生态系统中的配套工具的文章:编译器、IDE、调试器等。文章分门别类地对这些工具进行了介绍,对于 C++ 新手和老手都很友好,还有不少延伸阅读的链接,可以说是一篇拓展知识面的文章。

文章大致总结如下:

Tips

推荐一个 R 下面的科研辅助工具 BiblioShiny

作为科研工作者,我们经常希望有一款科研辅助工具,可以帮助我们更快地对所研究的领域有一个较为完整的了解。你可能听过大名鼎鼎的 Bibliomatrix,但它需要会编程的用户界面着实不太友好,那么现在你有了 Biblioshiny 这个图形化用户界面的工具。

Biblioshiny 可以帮助我们快速了解一下几个方面的问题:

  1. 这个领域里那些作者比较厉害?
  2. 哪些文献比较重要?
  3. 哪些主题更值得研究?

更多教程可以参考 Biblioshiny 的官方教程


Share

启动工作的两个技巧

最近和一个朋友讨论,发现他英语口语变好了(在法国,一般情况下如果你不刻意去练习,你很难让你的英语口语上升一个水平),我问他如何做到的,他回答道:我每天晚上下班回家之后,会再学一两个小时英语,重复一段 TED 的演讲。我有些惊讶:一般白天工作了七八个小时,你回家之后是如何能保持高效再学两个小时英语的?他说:我买了一个 380 欧的椅子,躺上去很舒服,于是我就更愿意坐到我的桌子前开始学习了。

说到如何启动工作,我也就和他分享了一个我最近受益良多的小技巧:坐到桌子前,开始做一件五分钟的小事,然后你就启动了,动量会驱使你继续工作下去。

类似的技巧我也分享给了实验室最近压力比较大的博三小哥。他问我如何强迫自己去锻炼身体的,我告诉他:the thing that you need to do in the first place, is to physically be in the gym.

所以,这周分享的两个技巧,让你更好的启动你的工作:

  1. 尽量营造一个舒适的、让你愿意去工作的环境
  2. 坐下来,开始工作五分钟