空间复杂度的相关知识---LingY

 空间复杂度

  上个文章,我们讨论了有关时间复杂度的一些知识,在时间复杂度之外,还有一个复杂度,叫做空间复杂度。

  算法的空间复杂度S(n)定义为该算法所耗费的存储空间,它是问题规模n的函数。记为

                                      S(n)=O(g(n));

  其中,n为问题的规模,g(n)是语句关于n所占存储空间的函数。

  我们先将视野投入到《大话数据结构》这本书中,它说:在一班般的情况下,一个程序在机器上执行的时候,除了需要存储程序本身的指令,常数,变量和输入数据外,还需要存储对数据操作的存储单元。

O(1)空间复杂度的例子

  针对于上面说的存储程序本身的指令等数据,作为一个初学者,我又参考了线上的公开课程

  从上图看一个算法所需要的内存空间,首先是与问题规模无关,大小固定的一些程序代码的保存  ,剩下的需要存储一个局部变量i和参数n,这两个只是一个int类型大小的数据,总共也只占八个字节,并不需要跟随n的变化而使得我们的内存开辟进行变化,所以算法运行多需要的内存空间是一个固定的常量,算法的空间复杂度也就是为O(1)。

O(n)空间复杂度的例子

  而我们将视野投放到下一张图

  这张图显示的代码,我们需要保存的就不仅仅是程序代码和几个int类型的数据了,我们需要开辟一个大小为4*n字节大小的数组,所以我们的内存存储空间大小并不固定,要随着n的变化而变化,所以上述代码的空间复杂度即为O(n)。

  我们对上面知识的总结可以得知:

  若输入数据所占空间只取决于问题本身,和算法无关,这样只需要分析该算法在实现时所需要的辅助单元即可。

  若算法执行时所需要的辅助空间相对于输入数据量而言是个常数,则称次算法为原地工作,空间复杂度为O(1)。

  关于我所理解的O(1)是,在原地工作,比如有关一个数组的调整,如果我们新开一个同样大小的数组进行修改好再将数组拷贝过去,这样的空间复杂度就是O(N),而如果我们是直接在原来数组上进行修改,我们就可以说这个算法的空间复杂度是O(1)。

函数递归的空间复杂度

  我们对于函数递归的空间复杂度的计算,我们首先需要知道的是对于空间,我们是可以重复利用的,对于时间,我们却是不可以进行重复利用的。

  对于空间的重复利用我们可以怎么理解呢??相信大家都住过宾馆吧,对于宾馆的某一间房间我们在退房后,酒店是不是可以再次将房间进行出租,让别人进行使用,对于空间的重复利用,我们也可以进行这样的理解。

  通过上图,我们可以看到,对于两个不同的函数调用,使他们生成一个变量,然后再对于这个变量的存储地址进行打印,我们可以看出,它们打印出来的地址都是一样的,这也证明了我们所说的,对于空间,我们是可以进行重复利用的。

理解了上述对于空间可以重复利用的观点,我们可以看一眼下面关于函数递归的空间复杂度

  上图对于斐波那契数列的空间复杂度,有的认为是O(2^n),但是我们刚刚已经讲过了,空间是可以重复利用的,函数递归会一直递归,递归到最深层,然后完成了这层递归后进行返回,释放掉底层递归所占用的空间后,再给别的函数递归进行使用,

  如上图,我们一直递归到Fib(2),然后进行返回,返回到Fib(3)后,再进行旁边的Fib(1)的递归,因为在返回到Fib(3)的时候,Fib(2)所占用的空间已经被释放,给予了Fib(1)。所以其实空间并没有进行简单的叠加,而是进行了重复的利用。

所以,斐波那契的函数递归的空间复杂度是O(N)。

空间换时间

  知道了检验一个算法的好坏,我们引用了时间复杂度与空间复杂度。在空间可以重复利用,而时间不能重复利用的前提下,我们可以适当的用空间来换取时间。例如下面这个问题:

对于这个题,我们会有几个想法对它进行实现,分别是

对于思路一,我们是一次一次进行操作,在原数组的情况下,我们可以将数组一个个进行右移一位,对于k次的旋转,假如是数组N的倍数,我们可以对这个数组不进行任何处理,这是这个问题下最好的情况,而最坏的情况呢,假如K%N=N-1的条件下,我们可以对其进行时间复杂度大概计算,计算出这个算法所需要的时间复杂度是O(N)。

我们可不可以将时间复杂度降低呢?答案肯定是毋庸置疑的,在节省时间的条件下,我们就需要去开辟一些新的空间,来辅助我们完成我们的目标。

  在面对同样问题的情况下,我们创造了一个新的数组,辅助我们进行了旋转的操作,我们对比原来的数组与旋转k次的数组,发现了变化后的数组是将N-K个元素放后面,K个元素放前面。

  针对于这个情况,我们可以新建一个数组,将变化后的数组元素按顺序放进去,然后再进行数组的拷贝。我们可以看出这个算法的时间复杂度是O(N),而上个算法的时间复杂度是O(N^2),两个算法的空间复杂度一个是O(1),而一个是O(N)。

  我们实现了时间复杂度的降低,采用了利用空间去换取时间的一种做法,在未来的前进途中,我们可以进行这种操作,来节省我们不可重复利用的时间!

  如果有什么错误,请大家多多指正,我也会在学习了新的知识后,对旧的知识进行更新与反思。希望大家多多支持。有错误也请麻烦大家多多指正。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值