1. 時間復雜度:
使用大O表示法來表示程序的時間復雜度
常見的7種時間復雜度(復雜度由低到高排序)
O(1):常數時間復雜度
O(log(n): 對數時間復雜度
O(n): 線性時間復雜度
O(n^2):平方時間復雜度
O(n^3):立方時間復雜度
O(k^n):指數時間復雜度,k表示常數
O(n!):階乘時間復雜度
ps:
這里我們並不考慮前邊的系數;O(1) 並不表示復雜度為1,也可以 是2、3等常數;O(n)表示程序運行了n次或者2n、3n次;以此類推其他時間復雜度
時間復雜度的判斷,以一段代碼的最高復雜度為准;
如何判斷一段代碼的時間復雜度
簡而言之就是看內部某段代碼的執行次數
O(1):常數復雜度
int n = 1;
System.out.println(n);
1
2
int n = 1;
System.out.println(n);
System.out.println(n+1)
System.out.println(n+2)
1
2
3
4
O(n):線性時間復雜度
for (int j = 0; j < n; j++) {
System.out.println(j);
}
1
2
3
for (int i = 0; i < n; i++) {
System.out.println(i);
}
for (int j = 0; j < n; j++) {
System.out.println(j);
}
1
2
3
4
5
6
O(n^2):平方時間復雜度
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.println(i + j);
}
}
1
2
3
4
5
O(n^3):立方時間復雜度
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
System.out.println(i + j);
}
}
}
1
2
3
4
5
6
7
O(log(n)): 對數時間復雜度
這里演示的是以2為底n的對數
for (int i = 0; i < n; i = i * 2) {
System.out.println(i);
}
1
2
3
O(2^n):指數時間復雜度
/**
* 遞歸求斐波那契數列的第n項;可以通過畫運行樹的方式獲得時間復雜度
*/
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
1
2
3
4
5
6
7
O(n!):階乘時間復雜度
todo
小練習1:求和計算1~n的和
O(n)
int y = 2;
for (int i = 0; i < n; i++) {
y+=i;
}
1
2
3
4
O(1)
使用了求和公式:sum = n(n+1)/2
int y = 2;
for (int i = 0; i < n; i++) {
y+=i;
}
1
2
3
4
小練習2:求斐波那契數列
O(2^n):
int fib(int n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
1
2
3
4
O(n):該方法比遞歸要快得多
int fib2(int n) {
if (n == 1 || n == 2) {
return 1;
}
int a = 1, b = 1, result = 0;
for (int i = 3; i <= n; i++) {
result = a + b;
a = b;
b = result;
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
主定理
主定理(英語:master theorem)提供了用漸近符號(大O符號)表示許多由分治法得到的遞推關系式的方法
常用算法中的應用
算法 遞回關系式 運算時間
二分搜尋算法
二叉樹遍歷
最佳排序矩陣搜索(已排好序的二維矩陣)
合並排序
所有排序的最優算法都是O(nlog(n))
2. 空間復雜度
如何判斷一段代碼的空間復雜度
主要通過兩部分進行判斷:
數組的長度
如果代碼中應用了數組,那么數組的長度,基本上就是空間復雜度;
e:一維數組的空間復雜度是O(n);二維數組的空間復雜度是O(n^2)
遞歸的深度
如果代碼中有遞歸,那么遞歸的深度,就是代碼的空間復雜度的最大值
ps:如果代碼中既有數組,又有遞歸,那么兩者的最大值就是代碼的空間復雜度
leecode有個爬樓梯的復雜度分析情況;可以進行練習
3. 數組和鏈表的時間復雜度分析
數組
隨機增加:O(n)
隨機查詢:O(1)
隨機刪除:O(n)
鏈表
隨機增加:O(1)
隨機查詢:O(n)
隨機刪除:O(1)
跳表
跳躍表(skiplist)是一種隨機化的數據, 由 William Pugh 在論文《Skip lists: a probabilistic alternative to balanced trees》中提出, 跳躍表以有序的方式在層次化的鏈表中保存元素, 效率和平衡樹媲美 —— 查找、刪除、添加等操作都可以在對數期望時間下完成, 並且比起平衡樹來說, 跳躍表的實現要簡單直觀得多。
簡單來說,跳躍表是有序鏈表的一種擴展,在有序列表的基礎上進行了升維處理