爬樓梯這個問題,其實思路是很明確的:爬到當前樓梯的方法數 = 爬到上一級樓梯(然後再爬一級,只有這一種選擇)的方法數 + 爬到上兩級樓梯(然後再爬兩級,只有這一種選擇)的方法數,也就是:
f (x
)=f(
x−1)
+f(x
−2
)f(x)=f(x-1)+f(x-2)
f(x)=f
(x−1
)+f(
x−2)
這個其實是老生常談了,它其實就是著名的斐波那契數列,可以迴圈或者遞迴求解,也可以用dp來剪枝,然後進一步對dp的陣列進行優化(所謂的滾動陣列),乃至矩陣快速冪、通項公式,或者更極端的直接打表(如果指定範圍的話),就不一一解釋了。
這裡舉個求通項公式的例子。我們可以看到這樣一段**:
function climbstairs(n: number): number
可以看到,這段**裡有大量的重複計算,比如重複了三次的math.sqrt(5)
。但是,這段**的執行結果,有時候卻比不重複計算的快:
function climbstairs(n: number): number
這個其實牽涉到v8的一些機制。v8作為著名的jit引擎,會對「熱點**」進行編譯,轉化成彙編**。也就是說,反覆執行的**就有概率會被編譯成彙編;反覆執行就是為了提醒v8,我這個**你可以優化。即使是重複執行幾次這種級別的彙編碼,也比只執行一次的需要翻譯的js**要快。這其實是很有意思的一件事,我在之前的文章裡稍微提過一點。
但是整個過程是不能控制的,具體是否會被編譯,如何編譯,我們都無法控制,類似於資料庫的優化器,以及cpp的inline機制,只是乙個「請求」而已。並且,如果由於種種原因,編譯過的**被放棄,會造成大量的反優化的開銷。所以為了穩定考慮,一般還是會提取乙個變數來避免重複運算;畢竟我們不能把寶押在js引擎上,不是嗎。
70 爬樓梯(簡單)
解題思路1 使用斐波那契序列 從第二個之後第n個結果為n 1,n 2項之和。使用遞迴呼叫。def climbstairs n if n 0 return 0if n 1 return 1if n 2 return 2if n 2 return climbstairs n 1 climbstairs ...
70 爬樓梯(簡單題)
假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2 輸出 2 解釋 有兩種方法可以爬到樓頂。1 階 1 階 2 階 示例 2 輸入 3 輸出 3 解釋 有三種方法可以爬到樓頂。1 階 1...
簡單演算法 33 爬樓梯
假設你正在爬樓梯。需要 n 步你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2輸出 2解釋 有兩種方法可以爬到樓頂。1.1 步 1 步2.2 步示例 2 輸入 3輸出 3解釋 有三種方法可以爬到樓頂。1.1 步 1...