时间复杂度,换句话说,就是它们运行得有多快。但有些时候,我们还得以另一种名为空间复杂度的度量方式,去估计它们会消耗多少内存。
当内存有限时,空间复杂度便会成为选择算法的一个重要的参考因素。比如说,在给小内存的小型设备写程序时,或是处理一些会迅速占满大内存的大数据时都会考虑空间复杂度。
描述空间复杂度的大O记法
计算机科学家还是用描述时间复杂度的大O记法来描述空间复杂度。 用大O来描述一个算法需要多少空间:当所处理的数据有N个元素时,该算法还需额外消耗多少元素大小的内存空间。
function makeUpperCase(array){//makeUpperCase函数接收一个数组作为参数array。 var newArray=[];//然后它创建了一个全新的数组,名为newArray for(var i=0; i < array.length; i++){ newArray[i]=array[i].toUpperCase();//并将原数组array里的字符串的大写形式填进去。 } return newArray; }
分析该函数的话,你会发现它接收一个N元素的数组,就会产生另一个新的N元素数组。因此,我们会说这个makeUpper-Case函数的空间效率是O(N)。
我们再写一个更高效利用内存的makeUpperCase。
function makeUpperCase(array){ for(var i=0; i < array.length; i++){ array[i]=array[i].toUpperCase(); } return array; }
因为该函数并不消耗额外的内存空间,所以我们把它的空间复杂度描述为O(1)。记住,时间复杂度的O(1)意味着一个算法无论处理多少数据,其速度恒定。相似地,空间复杂度的O(1)则意味着一个算法无论处理多少数据,其消耗的内存恒定。
值得一再强调的是,空间复杂度是根据额外需要的内存空间(也叫辅助空间)来算的,也就是说原本的数据不纳入计算。尽管在第二个版本里我们有array这一入参,占用了N个元素的空间,但除此之外它并没有消耗额外的内存,所以它是O(1)。(有些参考书在计算空间复杂度时是连原始输入也一起算的,那没问题。但此处我们不计算它,当你在其他地方看到某一算法的空间复杂度的描述时,最好留意一下它是否计算原始输入。)
我们比较一下makeUpperCase两个版本的时间复杂度和空间复杂度。
因为N项数据要花N步去处理,所以两个版本的时间复杂度都是O(N)。然而在空间复杂度方面,第二个版本只有O(1),与第一个版本的O(N)相比,它对内存的使用效率更高。
因此选择第二个版本更为合理。
参考:数据结构与算法图解.14
来源:https://www.cnblogs.com/ooo0/p/12161786.html