70.Climbing Stairs

题目链接:https://leetcode.com/problems/climbing-stairs/description/

题目大意:爬楼梯问题,一共花费n步爬到楼顶,一次可以爬一个台阶或两个台阶,求出一共有多少种方法可以爬到楼顶。

此题其实是裴波那挈数列问题。

法一:动规公式:fib[n] = fib[n - 1] + fib[n - 2]。用for循环数组来求fib[n],将其返回既是结果。代码如下(耗时0ms):

 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

法二(超时):直接递归,超时了,而且递归栈的深度也是一个问题。代码如下:

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):

 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

快速幂知识点:

快速幂:http://www.cnblogs.com/CXCXCXC/p/4641812.html

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

 借鉴:   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

 

posted on 2017-10-24 11:20  二十年后20  阅读(171)  评论(0编辑  收藏  举报

导航