【每日一題】LeetCode. 70. 爬樓梯

每日一題,防止癡呆 = =

一、題目大意

假設你正在爬樓梯。需要 n 階你才能到達樓頂。

每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是一個正整數。
在這裏插入圖片描述
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/climbing-stairs

二、題目思路以及AC代碼

今天的每日一題是兩年前做過的一道題 = =,也是一道比較經典的DP吧,下面我按照官解給出的多個思路的目的,一個個的說一下

思路一:動態規劃

這個肯定是可以用動態規劃求解的。我們令dp[i]表示爬i層臺階共有多少種方法,那麼我們又知道每次只能爬1或2個臺階,那麼dp[i] = dp[i-1] + dp[i-2],直接用DP解決即可,時間複雜度是O(n),然後我們發現其實這個DP只用到了三個數,所以空間複雜度就可以由O(n)優化到O(1)。

思路二:矩陣快速冪

我們發現,由上面提到的矩陣的遞推公式可以得到以下公式:
在這裏插入圖片描述
也就是說,我知道了f(0)和f(1)之後,我們可以通過不斷的乘一個固定的矩陣來得到想要的f(n),那其實就是一個求矩陣冪的問題,關於冪運算,我們是有快速冪的方法可以使得複雜度是O(logn)的,當然矩陣的乘法複雜度是O(1),然後空間複雜度也是O(1)。

思路三:直接用通項公式求解

這就是數學問題了,其實我們觀察遞推公式就可以發現,這個DP數組其實就是一個斐波那契數列,那麼我們就可以直接求通項公式,然後將n帶入求解,但這裏面會涉及到浮點數精度的問題,而且由於通項公式中含有冪次,所以時間複雜度還是O(logn),空間複雜度是O(1)。

AC代碼

這裏只將思路一中的DP寫一下,其實也就是在求斐波那契數列而已。

class Solution {
public:
    int climbStairs(int n) {
        if (n < 2) return 1;

        int first = 1;
        int second = 1;
        int third;
        
        for (int i=2;i<=n;i++) {
            third = first + second;
            first = second;
            second = third;
        }

        return third;
    }
};

如果有問題,歡迎大家指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章