[LeetCode]70. Climbing Stairs(求爬楼梯有几种方式)

70. Climbing Stairs

原题链接
You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

原题大意:

  • 给一个台阶数为n的楼梯,一次能跨一个或者两个台阶,写出一个函数算出有几种方式登顶

Note:

  • Given n will be a positive integer.(n是正整数)

思路:

  • 看到题目,首先想到了分类,每一类中(一个台阶一步)和(两个台阶一步)的数量是固定的
  • 各个类之间,一个台阶一步的数量减2,两个台阶一步的数量+1
  • 单个类,找出跨一步和两步的数量one, two,用排列组合的方法,总共one+one个空,
  • 随机插入one或者two,即可得到方法数,公式由下图给出(不会电脑作图,只能手机拍摄,见谅)
  • 这里写图片描述

代码如下:

#include <iostream>
using namespace std;
class Solution {
public:
    int climbStairs(int n) {
        if(n<=0) return 0;
        if(n==1) return 1;
        double res=0;//记录爬楼梯方式的数量 必须用double 否则会出现误差
        //one一步一个台阶的次数  two一步两个台阶的次数
        for(int one=n,two=0; (one>=0)&&(two<=n/2); one-=2,two++){
            if(one==0 || two==0)
                res += 1;
            else{
                double temp = factorial(one+two)/(factorial(one)*factorial(two)); //必须用double 否则会出现误差
                res += temp;
            }
        }
        return res;
    }
    double factorial(int n){
        if(n==0) return 1;//0的阶乘是0
        double res = 1;
        for(int i=2; i<=n; i++)
            res*=i;
        return res;
    }
};
int main()
{
    Solution s;
    int a = 0;
    cin >> a;
    cout << s.climbStairs1(a) << endl;
    return 0;
}

遇到的困难:

  • 由于用到了排列组合,我写了一个求阶乘的函数,但是阶乘很容易求得的结果超出int范围,总会出现误差,提示除数为0等一系列问题,我就把所有的int换成了double,执行AC了,有点侥幸的感觉。。。。。

探寻新方法:

  • 后来我去Disscuss看大家的思路,果然天外有人,总有新世界的大门打开
  • one_step_before表示最后一步登顶跨出一个台阶的方法数
  • two_steps_before表示最后一步登顶跨出两个台阶的方法数
  • 总方法数all_ways = one_step_before + two_steps_before
  • 用类似于fibonacci的方法求解
  • 附上链接

代码如下:

int climbStairs(int n) {
        if(n<=0) return 0;
        if(n==1) return 1;
        if(n==2) return 2;
        //one_step_before表示最后一步登顶跨出一个台阶的方法数
        //two_steps_before表示最后一步登顶跨出两个台阶的方法数
        //总方法数all_ways = one_step_before + two_steps_before
        //n=3时  对one_step_before,two_steps_before初始化
        int one_step_before = 2;
        int two_steps_before = 1;
        int all_ways = 0;//记录爬楼梯方式的总数
        for(int i=2; i<n; i++){
            all_ways = one_step_before + two_steps_before;
            two_steps_before = one_step_before;
            one_step_before = all_ways;
        }
        return all_ways;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值