本人在購買極客學院王爭老師的《數據結構與算法之美》後,覺得裏面的內容還不錯,適合新手入門,故將自己的學習筆記整理了下,做個記錄,供學習使用,另裏面存在個人理解,難保會有差錯,歡迎大家在評論區討論,侵刪。
極客學院專欄地址:https://time.geekbang.org/column/intro/126?gk_activity=0
筆記目錄: https://blog.csdn.net/lxfHaHaHa/article/details/101039494
時間複雜度又分爲最好情況時間複雜度(best case time complexity)、最壞情況時間複雜度(worst case time complexity)、平均情況時間複雜度(average case time complexity)、均攤時間複雜度(amortized time complexity)
一個例子:
// n 表示數組 array 的長度
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) {
pos = i;
break;
}
}
return pos;
}
這裏x有可能在數組裏面,也可能不在數組裏面,最好的情況是在第一個位置就找到了,最壞的情況要最後一位,即:
- 最好情況時間複雜度:O(1) — 第一位就找到
- 最壞情況時間複雜度:O(n) — 要全部遍歷完
- 平均情況時間複雜度:有兩種可能,在或者不在,在的話,n個位置都有可能,分別是1/2n的可能性,分別要走1到n步;不在的話,是1/2的可能,時間複雜度是n。故如下:
- 均攤時間複雜度:其實就是特殊情況下的平均情況時間複雜度,舉個例子:
// array 表示一個長度爲 n 的數組
// 代碼中的 array.length 就等於 n
int[] array = new int[n];
int count = 0;
void insert(int val) {
if (count == array.length) {
int sum = 0;
for (int i = 0; i < array.length; ++i) {
sum = sum + array[i];
}
array[0] = sum;
count = 1;
}
array[count] = val;
++count;
}
這裏最好爲O(1),最壞爲O(n),平均爲:
均攤:每一次 O(n) 的插入操作,都會跟着 n-1 次 O(1) 的插入操作,所以把耗時多的那次操作均攤到接下來的 n-1 次耗時少的操作上,均攤下來,這一組連續的操作的均攤時間複雜度就是 O(1)。這就是均攤分析的大致思路。
均攤總結:對一個數據結構進行一組連續操作中,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度比較高,而且這些操作之間存在前後連貫的時序關係,這個時候,我們就可以將這一組操作放在一塊兒分析,看是否能將較高時間複雜度那次操作的耗時,平攤到其他那些時間複雜度比較低的操作上。而且,在能夠應用均攤時間複雜度分析的場合,一般均攤時間複雜度就等於最好情況時間複雜度。