極客時間課程《數據結構與算法之美》01 - 複雜度

複雜度計算

O (logn)

i=1;
 while (i <= n)  {
   i = i * 2;
 }

實際效果:java

2^{0} *  2^{1} *  2^{2} ···  2^{k} ··· 2^{x}= n

經過 2x=n 求解 x 。
x=log2n,因此,這段代碼的時間複雜度就是O (log2n)。數組

無論底數是幾,全部對數階的時間複雜度都記爲
O (logn)。由於
O (log3n) = O(C * log2n),使用大O標記複雜度的時候,能夠忽略係數,因此贊成表示爲O (logn)。數據結構

好比,歸併排序、快速排序的時間複雜度都是 O (nlogn)。code

O(m+n)、O(m*n)
代碼複雜度由兩個數據的規模來決定。

int cal(int m, int n) {
  int sum_1 = 0;
  int i = 1;
  for (; i < m; ++i) {
    sum_1 = sum_1 + i;
  }

  int sum_2 = 0;
  int j = 1;
  for (; j < n; ++j) {
    sum_2 = sum_2 + j;
  }

  return sum_1 + sum_2;
}

其中m和n是表示兩個數據規模,沒法事先評估m和n哪一個大,因此不能隨意省略,故,上面代碼的時間複雜度就是 O (m+n)。排序

空間複雜度

void print(int n) {
  int i = 0;
  int [ ] a = new int[n];
  for (i; i <n; ++i) {
    a[i] = i * i;
  }

  for (i = n-1; i >= 0; --i) {
    print out a[i]
  }
}

第2行申請一個空間存儲變量i,能夠忽略,和n無關。
第三行申請了大小爲n的int類型數組,除此以外,無更多空間佔用。故複雜度爲O(n)。class

均攤時間複雜度

大部分狀況下,沒必要區分最好、最壞、平均狀況時間複雜度三種狀況。變量

// 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 (n) 的插入操做,都會跟着 n-1 次 O (1) 的插入操做,因此把耗時多的那次操做均攤到接下來的 n-1 次耗時少的操做上,均攤下來,這一組連續的操做的均攤時間複雜度就是 O (1)。這就是均攤分析的大體思路。方法

對一個數據結構進行一組連續操做中,大部分狀況下時間複雜度都很低,只有個別狀況下時間複雜度比較高,並且這些操做之間存在先後連貫的時序關係,這個時候,咱們就能夠將這一組操做放在一起分析,看是否能將較高時間複雜度那次操做的耗時,平攤到其餘那些時間複雜度比較低的操做上。並且,在可以應用均攤時間複雜度分析的場合,通常均攤時間複雜度就等於最好狀況時間複雜度。數據

均攤時間複雜度就是一種特殊的平均時間複雜度,不必花太多精力去區分它們。最應該掌握的是它的分析方法,攤還分析。至於分析出來的結果是叫平均仍是叫均攤,這只是個說法,並不重要。時間

新知

對於可反覆讀寫的存儲空間,認爲它空即爲空。清空數組有時候並不須要置爲0,或某個值。把下標指到第一個位置就能夠。

留言體會:平均和平攤基本就是一個概念,平攤是特殊的平均。在分析時間複雜度是 O (1) 仍是 O (n) 的時候最簡單就是憑感受,,,,,,,,出現 O (1) 的次數遠大於出現 O (n) 出現的次數,那麼平均平攤時間複雜度就是 O (1)。。。。

相關文章
相關標籤/搜索