时间复杂度(优先考虑)
大O阶表示法
1、用常数1取代运行时间中的所有加法常数
2、在修改后的运行次数中,只保留高阶项
3、如果最高阶项存在且常数因子不为1,则去除与这个项相乘的常数
示例
算法一: 3次 O(1)
算法二: n+3次 ====》 O(n)
算法三: n 2 + 2次 O(n 2)
常见的大O阶
-
线性阶 O(n)
public static void main(String[] args){ int sun = 0; int n = 100; for(int i = 1; i <= n; i++){ sum += i; } System.out.pringln(sum); }
-
平方阶 O(n)
public static void main(String[] args){ int sun = 0; int n = 100; for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ sum += i; } } System.out.pringln(sum); }
-
对数阶 O(logn)
int i=1,n=100;
while(i<n){
i = i * 2;
}
假设有x个2相乘后大于n,则会退出循环。由于 2 x = n ⇒ x = log2n
所以这个循环的时间复杂度是O(logn)
- 常数阶 O(1)
public static void main(String[] args){
int n = 100;
int i = n + 2;
System.out.pringln(i);
}
- 别的情况
一个存储了n个随机数字的数组,请从中查找出指定的数字
public int search(int num){
int[] arr = {11,10,8,9,7,22,23,0};
for(int i = 0; i< arr.length;i++){
if(num == arr[i]){
return i;
}
}
return -1;
}
空间复杂度
基本数据类型内存占用情况
计算机访问内存一次一个字节
一个引用需要8个字节
创建一个对象除了对象内部存储的数据占用内存,对象本身也有内存开销。每个对象自身开销16子节用来保存对象的头信息。
例如 Date date = new Date();
date这个变量需要占用8个字节来表示
new Date()自身开销16个子节用来保存头信息
一般内存使用,如果不够8个字节,都会被自动填充为8字节
public class A{
public int a =1;
}
通过new A() 创建一个对象的内存占用如下
1、整型成员变量a占用4个字节;
2、对象本身占用16个字节
==》总共需要20个字节,由于不是以8为单位会自动填充为24个字节
java中数组被限定为对象,他们一般会因为记录长度而需要额外的内存,一个原始数据类型的数组需要24字节的头部信息(16个自己的对象开销,4字节用于保存长度以及4个填充字符)再加上保存值所需的内存。
空间复杂度O(1)
O(8) ===> O(1)
public static int[] reverse(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;
}
空间复杂度O(n)
O(4n+24+4)===>O(n)
public static int[] reserves2(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;
}
java中有内存垃圾回收机制,jvm对程序的内存占用也有优化,无法精确的评估一个java程序的内存占用情况,但是了解java的基本内存占用使我们可以对java程序的内存占用情况进行估算。