时间和空间复杂度

本文详细介绍了衡量算法好坏的两个关键指标:时间复杂度(通过大O表示法分析循环结构)和空间复杂度(考虑存储空间需求)。通过实例解析了如何计算常见算法的时间复杂度,以及空间复杂度的计算方法。
摘要由CSDN通过智能技术生成

 一、如何衡量一个算法的好坏

   衡量一个算法的效率分为两种情况:

      1. 时间效率:时间复杂度

      2. 空间效率:空间复杂度

                

二、时间复杂度

   2.1 时间复杂度概念

         时间复杂度是算法中的基本操作执行的次数,被称为时间复杂度。

   因为我们在计算时间复杂度的时候,不一定要计算精确地执行次数,我们只需要粗略估计,知道大概次数就可以了,这里我们使用大O的渐进表示法。

   举例说明:

   我们可以看到:上述代码中有三个循环,第一行代码 int count = 0只执行一次,可以忽略。第一个是嵌套循环 ,i 循环 N-1 次,i 循环中的 j 也循环 N-1 次,忽略常数项,所以最中间的 count++ 代码循环N*N 次,第二个循环,k 循环 2*N 次,第三个循环,M循环10次。所以这个代码的时间复杂度为 N^2+2*N+10。我们忽略常数项,只保留最高项,最终时间复杂度为O(N^2)。

   2.2 推导大O 阶方法

1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。

 

   对于时间复杂度,我们一般分为三种情况:最好情况下,平均情况下,最坏情况下。我们在计算时间复杂度的时候,我们默认计算的是最坏情况下。

   三、常见时间复杂度的计算例子

实例一:

       推导过程: 上述代码两个循环,第一个循环执行 (2*N)-1 次,第二个循环执行 10 次,去除常数项,最后得出时间复杂度为 O(N)。

   实例二:

 

   推导过程:上述代码两个循环,第一个循环执行 M-1 次,第二个循环执行 N-1 次,所以他的时间复杂度为 O(M+N) ,和上一个代码的区别是这个代码的第二个循环还是未知项,所以不能弃掉。

   实例三:

   推导过程:这个代码参数为 N,但没有调用。循环最多的是 count++ 语句,循环了100次。对于常数项我们用 O(1) 表示,所以时间复杂度为 O(1)。

   实例四:

 

   推导过程:这是个冒泡排序语句,我们不能单纯凭借一个嵌套循环就说这个代码的时间复杂度为 O(N^2) ,要结合代码的思想。我们可以看出这是个等差数列,等差数列公式是首项加尾项乘以项数除以2,由此可得 ((1+(n-1))*(n-1))/2 ,最终得出时间复杂度为 O(N^2)。

   还有一个问题:这个代码最坏情况下的时间复杂度是多少呢,一般情况下代码的时间复杂度最好情况下是只运行一次,为O(1),但排序代码只运行一次显然是不现实的,只有一个数怎么排序呢,所以这个代码的最好情况下是有N个数,只运行一次就可以把这些数排序完成,时间复杂度为O(N)。

实例五:

   

   推导过程:这是个二分查找代码,关于时间复杂度我们也要遵循代码的思想。对于二分查找来说,查找的数在最后一个才被找到就是最坏情况。这个代码不断除以2直到找到想要的那个数。假设有N个数据,数据在不断除以2,就是2^y = n ,所以我们可以把这个代码的时间复杂度表示为O((log2)N)。

   实例六:

   推导过程:这个代码是个递归代码,没有循环,所以我们没办法通过循环确定是时间复杂度。一般情况下,递归的时间复杂度 = 递归的次数 * 递归后代码执行的次数。通过这个代码,这是个三目运算,因此递归后只执行一次,我们只需要确定代码循环多少次即可。假设我们N等于3,最后会递归2次,因此递归次数我们总结为N-1,1 * (N-1),去掉常数项,最后时间复杂度为O(N)。

   实例七:

 

   推导过程:这依然是个递归代码,fibonacci(N-1)+fibonacci(N-2) 可以理解为一个二叉树,

   F(5)=F(4)+F(3),F(4)=F(3)+F(2),F(3)=F(2)+F(1)……,由此我们得出:

 

   观察规律,他的递归次数为 2^n,F(N)的最后一项为F(n-(n-1)),F(N)的递归次数为  2^0 + 2^1 + 2^2 + 2^3 + …… + 2^(n-1) ,可以看出这是个等比数列,等比数列求和公式为:Sn=a1(q^n-1)/(q-1)。当前q 是 2 ,Sn=1 * (2^n-1) / (2-1) =2^n-1。去掉常数项,时间复杂度为O(2^N)。

   四、空间复杂度

   空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,也用大O的渐进表示法。空间复杂度对于现在来说实际意义已经不是很大了。

   实例一:

   对于空间复杂度来说,循环并不会另外开辟空间,所以这个代码是个常数项,空间复杂度用O(1)表示。

   实例二:

   

 

   这个代码申请了一个长数组,会将循环产生的变量存储到数组中,所以这个代码占用的空间被N所影响,空间复杂度为O(N)。

   实例三:

 

   这个递归代码每递归一次都会在栈上另外开辟一个空间,所以空间复杂度为O(N)。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值