时间复杂度与空间复杂度

作用

时间复杂度是用来衡量一个算法的运行速度的指标,空间复杂度则是用来衡量一个算法所需要的额外空间的指标。

大O表示法

在计算机科学里,大O表示法用来表示一个算法的上界。它通常用输入大小的函数来表示算法的最大运行时间,也可以用来表示内存占用。

推导原则

  1. 复杂度是常数量级,用常数1表示。比如复杂度为O(2),O(100),用O(1)表示。
  2. 只保留复杂度的最高阶项。比如O(n^2+n+2),用O(n^2)表示。
  3. 最高阶项存在,则省去最高阶项前面的系数。比如O(3n),用O(n)表示。

时间复杂度

概念

时间复杂度简单理解就是一个算法或是一个程序在运行时,所消耗的时间(或者代码被执行的总次数)。一个算法执行所耗费的时间,从理论上说,是不能算出来的。因此,时间复杂度不是计算一个程序跑的时间长短。

因为一个算法所花费的时间与其中语句的执行次数成正比例,所以使用算法中的基本操作的执行次数,作为算法的时间复杂度。

void func1(int n)
{
    int count=0;
    for(int i=0;i<n;i++)    //执行n次
    {
        for(int j=0;j<n;j++)//执行n次
        {
            ++count;
        }
    }
    for(int i=0;i<2*n;i++)    //执行2*n次
    {
        ++count;  
    }
    int m=10;
    while(--m)    //执行10次
    {
        ++count;

    }
    cout<<count<<endl;

}

所以,fun1的执行次数为O(n*n+2*n+10),按照大O表示法的原则,fun1的时间复杂度为O(n*n)。

递归函数的时间复杂度

公式:每次的操作次数*递归次数

类型

最好时间复杂度:任意输入规模的最小运行次数(下界)

最坏时间复杂度:任意输入规模的最大运行次数(上界)

平均时间复杂度:任意输入规模的期望运行次数

例如:在一个长度为N的数组中遍历查找一个特定的元素target

最好情况:起始元素为target,1次就能找到

最坏情况:结尾元素为target,需要遍历完前面的元素,需要N次

平均情况:N/2次找到

快排的时间复杂度

 void quicksort(vector<int>& nums,int l,int r)
    {
        if(l>=r) return;
        int tmp=nums[l];
        int left=l;
        int right=r;
        while(left<right)
        {
            while(left<right&&nums[right]>=tmp) right--;
            if(left<right) swap(nums[left],nums[right]);
            while(left<right&&nums[left]<=tmp) left++;
            if(left<right) swap(nums[left],nums[right]);
        }
        nums[left]=tmp;

        quicksort(nums,l,left-1);
        quicksort(nums,left+1,r);

    }

虽然有很多个while,但是对于数组中的每一个元素,一次递归函数只会遍历一次,所以一次递归函数的遍历次数为O(n)

快排首先要选一个元素作为基准,每次操作的作用是将小于等于基准的元素放到最终基准的位置target左边,大于等于基准的元素放到target的右边

理想的情况下,每次基准的位置为中间,这样只需要递归logn次,所以,快排的最好时间复杂度和平均时间复杂度为O(n*logn)

最坏情况下,每次递归,基准的位置都在最左边或者最右边,递归的次数为n次,所以快排的最坏时间度为O(n^2)

空间复杂度

函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等的空间)在编译期间已经确定,因此空间复杂度主要通过函数在运行时显式申请的额外空间来确定。

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少Byte的空间,所以空间复杂度算的是变量的个数

O(1):int i;

O(n):int[] arr;

O(n^2):int[][] arr;

​
void func(int n)
{
    int a=1;    //1个局部变量
    int b=2;    //1个局部变量
    int nums=new int[n];    //额外申请了n个变量
    for(int i=0;i<n;i++)    //i:1个局部变量
    {
        nums[i]=i;
    }
}

​

int nums=new int[n];//new了一个数组出来,这个数据占用的大小为n,所以空间复杂度为O(n)。

如果一个函数只使用局部变量和参数,不进行任何额外的内存分配,那么它的空间复杂度是O(1)。因为它所需的空间是固定的,与输入数据的大小无关。如果函数在运行时根据输入数据的大小动态分配了数组或其他数据结构,那么它的空间复杂度将取决于输入数据的大小,可能是O(n)或其他量级。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值