關於爬樓梯問題以及優化

題目是這樣的:

假設你正在爬樓梯,一共有N階樓梯。但每次你只能爬一階或者兩階,你能有多少種不同的方法爬到樓頂部?

初出茅廬,面試被問到,回家做個筆記記錄一下。

最先想到的應該是用遞歸的方法解:

複製代碼
複製代碼
public static int climbStairs1(int n) {
        int ways;
        if(n==1||n==2) {
            ways = n;
        }else {
            ways = climbStairs1(n-1)+climbStairs1(n-2);
        }
        return ways;
    }
複製代碼
複製代碼

這樣解表面固然沒毛病,但是學習算法的時候應該聽過遞歸的方法慎用,慎用,慎用!重要的事情說3遍...這個方法當N很大時,時間複雜度成指數型的增長,問題很大啊~

於是乎,面試官問道,你有什麼優化的方法嘛?(我有好的方法,不就直接寫出來了嘛?不過感覺面試官都喜歡由淺入深,( ̄▽ ̄)")

上網查詢了一下,確實有一些不一樣的方法:

複製代碼
複製代碼
public static int climbStairs2(int n) {
        if(n==0)
            return 1;
        int[] arr = new int[n+1];
        arr[0]=1;
        arr[1]=1;
        for(int i=2;i<=n;i++) {
            arr[i] = arr[i-1]+arr[i-2];
        }
        return arr[n];
    }
複製代碼
複製代碼

這個方法是利用動態規劃來解決問題的,利用數組來存儲有多少種方法(與第一種那個方法比,實際就是利用空間換取時間,即空間複雜度很大),當N很大的時候,仍會出現問題,不過對於面試來說的話應該足夠了...

網上有種斐波那契數列的通項公式,有大神還能想得起來,做得出來,也是很強

複製代碼
複製代碼
public static int climbStairs4(int n) {
         if (n == 0)
                return 1;
            if (n == 1 || n == 2)
                return n;
            int result = (int) Math.floor(
                    1 / Math.sqrt(5) * (Math.pow((1 + Math.sqrt(5)) / 2, n + 1) - Math.pow((1 - Math.sqrt(5)) / 2, n + 1)));
            return result;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章