聊聊时间复杂度和Fibonacci数列的优化

时间复杂度概念的核心点:
时间复杂度就是函数走了多少次。
在计算时间复杂度的时候只是考量最坏的情况。
关注式子中增长最快的表达式,忽略其他。
忽略常数。

我们需要将时间复杂度的求解放在不同的情况下:
1.简单情况,一些循环啊什么的。
2.二分算法(分治法) 二分查找算法、堆算法 ,完全二叉搜索树和满二叉搜索树。 快速排序、归并排序 log2(N)。
3.递归算法:递归的次数*每次递归里面的时间复杂度。

主要讨论一下二分运算的时间复杂度:
以二叉树为例 如下图:

这里写图片描述

这里写图片描述

对于完全二叉树或者满二叉树,如果是搜索树,那么搜索的时间复杂度就是树的高度,因为折半查找和满二叉搜索树都是加了条件判断的,每次都将范围缩小一半,使得时间复杂度控制在lgN。
所以在后面的计算中,条件判断是不会算入时间复杂度的。而时间复杂度是在所有的条件都加上了之后最差的走的次数。

Fibonacci数列的递归与非递归:

这里写图片描述

后一个数是前两个数的和。

这里写图片描述

方案一: 递归
时间复杂度: O(2^N)(這个需要画图,但是不####太清楚,可能面试官会问到怎么算的)
空间复杂度: O(N)(最多递归了N层)
long long Fibonacci2(long long n)
{
    //assert(n);
    if (n == 0)
         return 0;
    if (n == 1)
         return 1;
    return Fibonacci2(n - 1) + Fibonacci2(n - 2);
}
递归存在的问题: 如果输入的数字过大,就可能会带来栈溢出。
方案二: 非递归,使用循环, 时间复杂度: o(N) 空间复杂度o(N)
//使用数组和循环,把数列放进去
//时间复杂度是o(N)   空间复杂度:o(N)  :开辟的空间大小是N个,所以空间复杂度是o(N)
long long FibonacciR1(long long n)
{
    long long* Fibarr = new long long[n + 1];
    Fibarr[0] = 0;
    Fibarr[1] = 1;
    for (long long i = 2; i <= n; i++)
    {
         Fibarr[i] = Fibarr[i - 1] + Fibarr[i - 2];
    }
    return Fibarr[n];
}
方案三:优化非递归 使用循环,时间复杂度o(N) 空间复杂度为o(1)
long long FibonacciR2(long long n)
{
    long long Fibarr[3] = { 0, 1, n };
    for (long long i = 2; i <= n; i++)
    {
         Fibarr[2] = Fibarr[0] + Fibarr[1];
         Fibarr[0] = Fibarr[1];
         Fibarr[1] = Fibarr[2];
    }
    return Fibarr[2];
}

小结:
关于空间复杂度: 实际上空间复杂度就是对象的个数,或者说开辟的空间单元的个数。(按照某一种状态中对象个数出现次数最多的情况算)
对于递归的空间复杂度,就是递归的层数*每次递归中的对象个数。
如果说這个程序里面开辟了N个元素的数组,那么空间复杂度就是N。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值