細化時間復雜度分析
代碼千千萬,有些代碼邏輯會很復雜,所以為了更細化的分析算法的復雜度,再復雜度分析方面引入了4個知識點:
1.最好情況時間復雜度(best case time complexity)。
2.最壞情況時間復雜度(worst case time complexity)。
3.平均情況時間復雜度(average case time complexity)。
4.均攤時間復雜度(amortized time complexity)。
復雜度分析
示例如下(限定條件:0<n且0<x且n和x為整數):
1 public int Function(int n, int x) 2 { 3 int sum = 0; 4 for (int i = 1; i <= n; ++i) 5 { 6 if (i == x) 7 break; 8 sum += i; 9 } 10 return sum; 11 } 12 /* 13 * 作者:Jonins 14 * 出處:http://www.cnblogs.com/jonins/ 15 */
這段代碼邏輯非常簡單,再此不描述。需要重點分析的是循環這一段代碼,這段代碼根據x值的不同,時間復雜度也有區別:
1.當x>n時,此代碼的時間復雜度是O(n)。
2.當1<=x<=n時,時間復雜度是一個我們不確定的值,取決於x的值。
3.當x=1時,時間復雜度是O(1)。
這段代碼在不同情況下,其時間復雜度是不一樣的。所以為了描述代碼在不同情況下的不同時間復雜度,我們引入了最好、最壞、平均時間復雜度。
最好情況時間復雜度
最好情況時間復雜度,表示在最理想的情況下,執行這段代碼的時間復雜度。
上述示例就是當x=1的時候,循環的第一個判斷就跳出,這個時候對應的時間復雜度就是最好情況時間復雜度。
最壞情況時間復雜度
最壞情況時間復雜度,表示在最糟糕的情況下,執行這段代碼的時間復雜度。
上述示例就是n<x的時候,我們要把整個循環執行一遍,這個時候對應的時間復雜度就是最壞情況時間復雜度。
平均情況時間復雜度
最好和最好情況是極端情況,發生的概率並不大。為了更有效的表示平均情況下的時間復雜度,引入另一個概念:平均情況時間復雜度。
分析上面的示例代碼,判斷x在循環中出現的位置,有n+1種情況:1<=x<=n 和n<x。
我們將所有情況下代碼執行的次數累加起來((1+2+3....+n)+n),然后再除以所有情況數量(n+1),就可以得到需要遍歷次數的平均值。
平均情況復雜度為:
$ \frac{((1+2+3...+n)+n)}{(n+1)}=\frac{n(n+3)}{2(n+1)} $
推導過程:
$ \because 1+2+3...+n=n+(n-1)+(n-2)...+1 $
$ \therefore (1+2+3...+n)=\frac{n(1+n)}{2} $
$ \therefore (1+2+3...+n)+n= \frac{n(3+n)}{2} $
大O表示法,會省略系數、低階、常量,所以平均情況時間復雜度是O(n)。
但是這個平均復雜度沒有考慮各自情況的發生概率,這里的n+1個情況,它們的發生概率是不一樣的,所以還需要引入各自情況發生的概率再具體分析。
x要么在1~n中,要么不在1~n中,所以它們的概率都是$\frac{1}{2}$。
同時數據在1~n中各個位置的概率都是一樣的為$\frac{1}{n}$。根據概率乘法法則,x在1~n中任意位置的概率是$\frac{1}{2n}$。
因此在前面推導過程的基礎上,我們把每種情況發生的概率考慮進去,那么平均情況時間復雜度的計算過程變成:
考慮概率的平均情況復雜度為:
$(1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})+n\frac{1}{2}=\frac{3n+1}{4}$
推導過程:
$\because (1+2+3...+n)=\frac{n(1+n)}{2}$
$\therefore (1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})=\frac{1}{2n}(1+2+3...+n)=\frac{1}{2n}*\frac{n(1+n)}{2} =\frac{1+n}{4}$
$\therefore (1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})+n\frac{1}{2}=\frac{1+n}{4} +n\frac{1}{2}=\frac{3n+1}{4}$
這就是概率論中的加權平均值,也叫做期望值,所以平均時間復雜度全稱叫:加權平均時間復雜度或者期望時間復雜度。
引入概率之后,平均復雜度變為O($\frac{3n+1}{4}$),忽略系數及常量后,最終得到加權平均時間復雜度為O(n)。
注意:
多數情況下,我們不需要區分最好、最壞、平均情況時間復雜度。只有同一塊代碼在不同情況下時間復雜度有量級差距,我們才會區分3種情況,為的是更有效的描述代碼的時間復雜度。
均攤情況時間復雜度
均攤復雜度是一個更加高級的概念,它是一種特殊的情況,應用的場景也更加特殊和有限。
對應的分析方式稱為:攤還分析或平攤分析。
示例如下(限定條件:0<=x<=n且0<=n且n,x為整數):
1 int n; 2 int Function2(int x) 3 { 4 int count = 0; 5 if (n == x) 6 { 7 for (int i = 0; i < n; i++) 8 { 9 count += i; 10 } 11 } 12 else 13 count = x; 14 return count; 15 } 16 /* 作者:Jonins 17 * 出處:http://www.cnblogs.com/jonins/ 18 */
分析上述案例的時間復雜度:
最理想情況下x!=n,只執行一次賦值即可推出,所以最好時間復雜度為O(1)。
最壞的情況下x=n,要執行一次循環累加和的操作,所以最好時間復雜度為O(n)。
平均的情況下,因為限定條件0<=x<=n,x在0~n中存在的位置可以分為n+1種情況(0到n)。
當0<=x<n時,時間復雜度為O(1)。但是x=n的時候是一個例外,它的復雜度是O(n)。
而且這n+1種情況發生的概率都是一樣的,為$\frac{1}{n+1}$。所以根據加權平均的計算方法,
平均時間復雜度為:
$ (1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+...+1\tfrac{1}{n+1})+n\tfrac{1}{n+1} = \tfrac{2n}{n+1} $
推導過程:
$(1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+...+1\tfrac{1}{n+1})+n\tfrac{1}{n+1}$
$=n\tfrac{1}{n+1}+n\tfrac{1}{n+1}$
$=\tfrac{2n}{n+1}$
當省略系數及常量后,平均時間復雜度為O(1)。
攤還分析法
分析上述示例的平均復雜度分析並不需要如此復雜,無需引入概率論的知識。
因為通過分析可以看出,上述示例代碼復雜度大多數為O(1),極端情況下復雜度才較高為O(n)。同時復雜度遵循一定的規律,一般為1個O(n),和n個O(1)。針對這樣一種特殊場景使用更簡單的分析方法:攤還分析法。
通過攤還分析法得到的時間復雜度為均攤時間復雜度。
大致思路:每一次O(n)都會跟着n次O(1),所以把耗時多的復雜度均攤到耗時低的復雜度。得到的均攤時間復雜度為O(1)。
應用場景:均攤時間復雜度和攤還分析應用場景較為特殊,對一個數據進行連續操作,大部分情況下時間復雜度都很低,只有個別情況下時間復雜度較高。而這組操作其存在前后連貫的時序關系。
這個時候我們將這一組操作放在一起分析,將高復雜度均攤到其余低復雜度上,所以一般均攤時間復雜度就等於最好情況時間復雜度。
注意:均攤時間復雜度是一種特殊的平均復雜度(特殊應用場景下使用),掌握分析方式即可。