Leetcode---爬楼梯

简介: Leetcode---爬楼梯

问题描述:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2

输出:2

解释:有两种方法可以爬到楼顶。

1. 1 阶 + 1 阶

2. 2 阶

示例 2:

输入:n = 3

输出:3

解释:有三种方法可以爬到楼顶。

1. 1 阶 + 1 阶 + 1 阶

2. 1 阶 + 2 阶

3. 2 阶 + 1 阶

 

提示:

1 <= n <= 45

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/climbing-stairs

 

解题:

n=1   ==> 1

n=2   ==>1+1 / 2

n=3  ==>到达第三层只能从第一层或者第二层到达,所以1+2

n=4 ==>到达第四层只能从第二层或者第三层到达,所以2+3

依次类推:f(n) = f(n-1)+f(n-2)

1.拿到这道题,第一个冒出来的想法就是用暴力递归写。提交发现超时。

n=45时,2^45==>大概会计算这么多次

class Solution {
public:
    int climbStairs(int n) {
       if(n == 1){
          return 1;
      }else if(n == 2){
          return 2;
      }else{
          return  climbStairs(n-1)+climbStairs(n-2);
     }
};

2.记忆化递归,通过一个数组来记录已经计算过的结果,减少计算次数。

O(n)

class Solution {
public:
    int *munber;
    int f(int n){
        if(munber[n] > 0){
            return munber[n];
        }
        if(n == 1){
            munber[1] = 1;
        }else if(n == 2){
            munber[2] = 2;
        }else{
            munber[n] = f(n-1)+f(n-2); 
        }
        return munber[n];
    }
    int climbStairs(int n) {
       munber = new int[n+1];
       return f(n);
       delete []munber;            //记得释放内存
    }
};

3.再分析,发现是一个典型的动态规划题(自底向上)

class Solution {
public:
    int climbStairs(int n) {
       int dp[n+1];
       dp[1] = 1;
       dp[2] = 2;
       for(int i=3;i<=n;i++){
           dp[i] = dp[i-1]+dp[i-2];
       }
       return dp[n];
    }
};

4.联想斐波那契数列,再优化

class Solution {
public:
    int climbStairs(int n) {
      int f1=1;
      int f2=2;
      int fn;
       for(int i=3;i<=n;i++){
           fn = f1+f2;
           f1 = f2;
           f2 = fn;
       }
       return fn;
    }
};

5.公式解:Binet's Formula

这个解法我也不晓得,看了别人的写法。可以背下来,如果要推原理的话,需要用到矩阵的知识。

f(n) = f(n-1) + f(n-2)

       那么可以得到特征方程:

                               x^2 = x^1 + x^0

       方程的两个解为:x1=[1-5^(1/2)]/2   x2=[1+5^(1/2)]/2

       不妨设通向公式为:

                               f(n) = c1x1^n+c2x2^n

       由于f(1) = 1、f(2) = 1

                               c1 = 1/5^(1/2)    c2 = -1/5(1^2)

       所以:f(n) = 1/5^(1/2)*{[1-5^(1/2)]/2} ^n + -1/5(1^2)*{[1+5^(1/2)]/2} ^n

       斐波那契第n项的结果为:

           

我们的初始条件: f(1)=1     f(2)=2

                    由前面的公式算的f(n+1)为我们题目的f(n)的解

class Solution {
public:
    int climbStairs(int n) {
       double sqrt5 = sqrt(5);
       double fib = pow((1+sqrt5)/2,n+1)-pow((1-sqrt5)/2,n+1);
       return round(fib/sqrt5);
    }
};
相关文章
|
6月前
|
算法
算法每日一题---两数之和
算法每日一题---两数之和
30 0
|
6月前
|
算法
LeetCode刷题---283. 移动零(双指针)
LeetCode刷题---283. 移动零(双指针)
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
6月前
|
存储 索引
题目----LeeCode热题100--1 两数之和
题目----LeeCode热题100--1 两数之和
43 1
|
6月前
|
索引
力扣---最长回文子串(动态规划)
力扣---最长回文子串(动态规划)
|
6月前
|
算法 Java
LeetCode算法题---两数之和(一)
LeetCode算法题---两数之和(一)
55 0
|
算法
LeetCode每日1题--螺旋矩阵
LeetCode每日1题--螺旋矩阵
72 0
LeetCode每日1题--螺旋矩阵
|
存储
|
算法
递归题目练习---爬楼梯
递归题目练习---爬楼梯
103 0