LeetCode 509. 斐波那契数 70. 爬楼梯

509. 斐波那契数

斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
给定 N,计算 F(N)。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fibonacci-number

一眼望去非常简单,递归几行解决问题
class Solution {
    public int fib(int N) {
        if(N==0){
            return 0;
        }else if(N==1){
            return 1;
        }else{
            return fib(N-1)+fib(N-2);
        }
    }
}

问题在于,由于此问题中,递归是Q(n)递归为计算Q(n-1)和Q(n-2),这就导致了:
N=调用次数
n1
n-11
n-22
n-33
n-45
n-58
n-613
可以看出,随着N和n的距离增加,函数的调用次数是增加的,而调用次数正好也是一个斐波那契数列(n-i会被n-i+1和n-i+2调用)

到了n-19,已经要被调用6000多次!

那么,我们把之前的运算结果都存起来,不就可以避免重复调用了吗!(牺牲一定堆内存换取效率(似乎也节省了栈内存))

class Solution {
    public int fib(int N) {
        //用来存fib(n)
        int re[] =new int[N+1];
        if(N==0){
            return 0;
        }
        re[1]=1;
        for(int i=2;i<N+1;i++){
            re[i]=re[i-1]+re[i-2];
        }
        return re[N];
    }
}

能不能再节省一点?

计算只用到前两个结果

所以,可以! 只用三个int类型存中间结果就行了!

class Solution {
    public int fib(int N) {
        int small=0;
        int big=1;
        int temp;
        for(int i=0;i<N;i++){
            temp=small+big;
            small=big;
            big=temp;
        }
        return small;
    }    
}

还有更简单的

康康这个:

斐波那契数列通项公式推导

还有什么事是数学解决不了的吗?

class Solution {
    public int fib(int N) {
        return (int)Math.round(Math.pow((1 + Math.sqrt(5)) / 2, N)/ Math.sqrt(5));
    }
}

然鹅,内存消耗还是感人


LeetCode中内存消耗最低的例程就是第三种解法,然鹅我拿去跑依旧5%

70. 爬楼梯

70层是从69和68分别爬1步和2步上来的

是不是似曾相识?

是的这题本质上就是求解斐波那契数列

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值