70.Climbing Stairs

題目連接:https://leetcode.com/problems/climbing-stairs/description/html

題目大意:爬樓梯問題,一共花費n步爬到樓頂,一次能夠爬一個臺階或兩個臺階,求出一共有多少種方法能夠爬到樓頂。數組

此題實際上是裴波那挈數列問題。ide

法一:動規公式:fib[n] = fib[n - 1] + fib[n - 2]。用for循環數組來求fib[n],將其返回既是結果。代碼以下(耗時0ms):spa

 1     public int climbStairs(int n) {
 2         int[] fib = new int[1000];
 3         fib[0] = 1;
 4         fib[1] = 1;
 5         fib[2] = 2;
 6         for(int i = 3; i <= n; i++) {
 7             fib[i] = fib[i - 1] + fib[i - 2];
 8         }
 9         return fib[n];
10     }
View Code

法二(超時):直接遞歸,超時了,並且遞歸棧的深度也是一個問題。代碼以下:.net

1 public int climbStairs(int n) {
2         if(n == 0 || n == 1) {
3             return 1;
4         }
5         else if(n == 2) {
6             return 2;
7         }
8         return climbStairs(n - 1) + climbStairs(n - 2);
9     }
View Code

法三(借鑑):實際上是法二的改進版,記憶性遞歸,用數組記錄已經計算過的fib[i],若是已經計算過則直接返回不用再繼續遞歸。代碼以下(耗時0ms):3d

 1 public int climbStairs(int n) {
 2         int[] fib = new int[1000];
 3         for(int i = 0; i <= n; i++) {
 4             fib[i] = 0;
 5         }
 6         return fib(fib, n);
 7     }
 8     
 9     public int fib(int[] fib, int n) {
10         if(n == 0 || n == 1) {
11             return 1;
12         }
13         else if(n == 2) {
14             return 2;
15         }
16         if(fib[n] != 0) {
17             return fib[n];
18         }
19         else {
20             fib[n] = fib(fib, n - 1) + fib(fib, n - 2);
21             return fib[n];
22         }
23     }
View Code

快速冪知識點:code

快速冪:http://www.cnblogs.com/CXCXCXC/p/4641812.htmlhtm

快速冪取模:http://www.cnblogs.com/lj-1568/p/4754336.htmlblog

 借鑑:   http://blog.csdn.net/hanleijun/article/details/24550065遞歸

https://leetcode.com/problems/climbing-stairs/solution/

 1 package problem_70;
 2 
 3 public class MatrixTest {
 4 
 5     static int[][] matrix;
 6     
 7     public static void main(String[] args) {
 8         init(2);  
 9         matrix[0][0] = 1;  
10         matrix[0][1] = 1;  
11         matrix[1][0] = 1;  
12         matrix[1][1] = 0;  
13         int[][] temp = new int[matrix.length][matrix.length];  
14         temp = pow(4);  
15         for (int[] a : temp) {  
16             for (int b : a) {  
17                 System.out.print(b + " ");  
18             }  
19             System.out.println();  
20         }  
21         System.out.println("斐波那契數列的fn值爲:" + temp[0][1]);  
22     }
23     
24     //初始化矩陣
25     public static void init(int n) {  
26         matrix = new int[n][n];  
27     }  
28   
29     //矩陣相乘
30     public static int[][] matrixMulti(int[][] m, int[][] n) {  
31         int[][] temp = new int[matrix.length][matrix.length];  
32         for (int k = 0; k < matrix.length; k++) {  
33             for (int i = 0; i < matrix.length; i++) {  
34                 for (int j = 0; j < matrix.length; j++) {  
35                     temp[k][i] += m[k][j] * n[j][i];  
36                 }  
37             }  
38         }  
39         return temp;  
40     }  
41   
42     //矩陣快速冪
43     public static int[][] pow(int n) {  
44         int[][] temp = new int[matrix.length][matrix.length];  
45         if (n == 1) {  
46             return matrix;  
47         } else {  
48             if (n % 2 != 0) {  //奇數
49                 temp = pow((n - 1) / 2);  
50                 temp = matrixMulti(temp, temp);  
51                 return matrixMulti(temp, matrix);  
52             } else {  //偶數
53                 temp = pow(n / 2);  
54                 temp = matrixMulti(temp, temp);  
55                 return temp;  
56             }  
57         }  
58     }  
59 }
View Code

法四(借鑑):數學方法

1 public class Solution {
2     public int climbStairs(int n) {
3         double sqrt5=Math.sqrt(5);
4         double fibn=Math.pow((1+sqrt5)/2,n+1)-Math.pow((1-sqrt5)/2,n+1);
5         return (int)(fibn/sqrt5);
6     }
7 }
View Code
相關文章
相關標籤/搜索