数据结构:空间复杂度

引言:上篇文章我们讲述了时间复杂度,这篇文章我们进一步讲解一下空间复杂度的内容。

空间复杂度

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。 函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

410d5f3963f24b6781804930192945b4.png

上面是两个很简单的空间复杂度的问题,一般情况下,空间复杂度都是O(N),O(1)

638cfdfa948144e9ae6fcf0686f523d9.png

49c221290a224be683b86e5f89736e1f.png

 上面两个实例都是和斐波那契数列相关的,但是我们就产生了一个问题,就是实例8它拓展过程中到底申请了多少空间,空间复杂度究竟如何计算,这里我们对这两个斐波那契数列的原理进行一下详细说明:

3557b6101a7c456a908d042c31b391dd.png

实例3的图示如上图,可以看到,它是一层一层往下开辟空间的,所以是真真实实地申请了N个大小的空间 

ebcb685b73fa4ffa8b8031fccf42fc0d.png

上图是实例8 在研究实例8之前,我们插入一小段内容以便加深理解,

a7afe0874d874b6e90cb38a5e8625f15.png

如图,a和b所使用的是同一块空间,这里是主函数出发,F1进入,申请了一块空间,F1结束,这块空间是要被销毁的,但是这个时候栈帧销毁是把它还给了系统中而并非彻底销毁,也就是说下一次也就是F2执行的时候,b和a使用的是同一块空间,相当于a和b住酒店,a先住,住完退房给b住,实际上他们是在一个房间住的,房间并没有被销毁,只是还给了房管。

5e3fa017e97b441b8f11d5593fa9b98d.png

这里是因为在F1里使用到了F2,这个时候只能再开辟一块空间,就好比住房,a还没退房,b就要来住房,那没办法,只能再给b找一间屋子,所以就开辟了两块空间。

明白了上面的道理,我们就来看斐波那契数列, 这里是fibN下放到N-1,然后再到N-2,一直到2,然后递归回去的时候会栈帧销毁,这样全部递归完毕后下一次下放的时候会再次申请同样的空间,所以它开辟出开的空间大小不变,还是N,所以最后空间复杂度是O(N)。

一言以蔽之:时间一去不复返,不可以重复使用;空间用了以后归还,可以重复利用。

下面我们插入一道力扣上面的复杂度OJ练习题:

1294858405584962924b4147da056e65.png ​​

力扣

对这道题,我们在这里提供两个思路:

思路一:

4 3 2 1 5 6 7 ---前n-k个逆置       4 3 2 1 7 6 5 ---后k个逆置       5 6 7 1 2 3 4 ---整体逆置

void reserve(int *nums,int begin,int end)
{
    while(begin<end)
    {
        int tmp=nums[begin];
        nums[begin]=nums[end];
        nums[end]=tmp;
        ++begin;
        --end;
    }
}

void rotate(int* nums, int numsSize, int k){
    k%=numsSize;
    reserve(nums,0,numsSize-k-1);
    reserve(nums,numsSize-k,numsSize-1);
    reserve(nums,0,numsSize-1);
}

时间复杂度O(N),空间复杂度O(1)

思路二:

使用memcpy函数

void rotate(int* nums, int numsSize, int k){
    k%=numsSize;
    int* tmp=(int*)malloc(sizeof(int)*numsSize);
    memcpy(tmp,nums+numsSize-k,sizeof(int)*k);
    memcpy(tmp+k,nums,sizeof(int)*(numsSize-k));
    memcpy(nums,tmp,sizeof(int)*numsSize);
    free(tmp);
    tmp=NULL;
}

memcpy函数第一个参数是要拷贝到的位置,第二个参数是开始拷贝的位置,第三个参数是拷贝的位数

时间复杂度O(N),空间复杂度O(N)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值