一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
空间复杂度
-
算法的空间复杂度计算公式:
S(n) = 0( f(n) ),其中 n 为输入规模,f(n)为语句关于 n 所占存储空间的函数 -
一个算法在计算机存储器上所占用的存储空间,包括三个方面
- 存储算法本身所占用的存储空间
- 算法的输入输出数据所占用的存储空间
- 算法在运行过程中临时占用的存储空间
案例:指定的数组进行反转,并返回反转的内容
解法一:
public static int[] reverse1(int[] arr) {
int n = arr.length; //申请4个字节
int temp; //申请4个字节
for (int start = 0, end = n - 1; start <= end; start++, end--) {
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
return arr;
}
- 空间复杂度为:
S(n) = 4+4 = O(8) = O(1)
解法二:
public static int[] reverse2(int[] arr) {
int n = arr.length; //申请4个字节
int[] temp = new int[n]; //申请n*4个字节+数组自身头信息开销24个字节
for (int i = n - 1; i >= 0; i--) {
temp[n - 1 - i] = arr[i];
}
return temp;
}
- 空间复杂度为:
S(n) = 4+4n+24 = O(n+28) = O(n)
根据大O推导法则,算法一的空间复杂度为0(1),算法二的空间复杂度为0(n),所以从空间占用的角度讲,算法一要优于算法二。
由于java中有内存垃圾回收机制,并且jvm对程序的内存占用也有优化(例如即时编译) , 我们无法精确的评估一个java程序的内存占用情况,但是了解了java的基本内存占用,使我们可以对java程序的内存占用情况进行估算。
由于现在的计算机设备内存一般都比较大,基本上个人计算机都是4G起步,大的可以达到32G ,所以内存占用一般情况下并不是我们算法的瓶颈,普通情况下直接说复杂度,默认为算法的时间复杂度。
但是,如果你做的程序是嵌入式开发,尤其是一些传感器设备上的内置程序,由于这些设备的内存很小, 一般为几kb,这个时候对算法的空间复杂度就有要求了,但是一般做java开发的,基本上都是服务器开发, 一般不存在这样的问题。