簡體   English   中英

如何衡量該算法的時間復雜度(Big-O)?

[英]How to measure the time-complexity (Big-O) of this algorithm?

我試圖測量以下算法的大O復雜度:

int sumSome(int[] arr){
   int sum = 0;
   for (int i=0; i<arr.length;  i++) {
      for (int j=1; j<arr.length; j = j*2) {
         if (arr[i] > arr[j])
            sum += arr[i];
      }
   }
   return sum;
}

現在從我的理解,

if (arr[i] > arr[j])
                sum += arr[i];

O(1)有很大的O,因為它是常數並且沒有任何事情發生,但是聽起來它的for循環雖然我很難分辨它的Big-O表示法。 我認為

for (int j=1; j<arr.length; j = j*2) {
         if (arr[i] > arr[j])
            sum += arr[i];
}

是一個線性函數O(n),因為j可能是1但它在O(2n)處以線性方式上升,這只是O(n)。 那么整個算法不是O(n ^ 2)嗎? 顯然我沒有在MOOC考試中正確回答這個問題。 謝謝!

是一個線性函數O(n),因為j可能是1但它在O(2n)處以線性方式上升,這只是O(n)。 因此,整個算法不會是O(n ^ 2)。 顯然我沒有在MOOC考試中正確回答這個問題。 謝謝!

它不是線性上升,而是呈指數上升,因為你在每次迭代時將j乘以2

j = 1, 2, 4, 8, 16, 32, ..., 2^k < n
2^k < n | apply log base 2 => k < log_2 n => k = O(log n)

所以第二個循環只執行O(log n)次,使整個代碼序列為O(n log n)

嚴格來說, O(n^2)也是一個正確的答案,因為如果O(n log n)是一個上界,那么O(n^2) 然而, n^2大Theta不正確,人們通常也會使用Big-Oh來指代嚴格的界限。

Big-O的關鍵是尋找循環,所以你的關鍵部分在這里:

for (int i=0; i<arr.length;  i++) {
   for (int j=1; j<arr.length; j = j*2) {
      if (arr[i] > arr[j])
         sum += arr[i];
   }
}

外循環執行N次,因為它以0為增量從0到N.

內部循環每次外部迭代執行Log N次,因為它以指數方式從1到N執行。 (我懷疑,你錯過的那個是循環中的迭代器: j = j*2這使得J呈指數增長,而不是線性增長,因此它將在log-base-2時間內達到N.如果它是+2 ,而不是*2

if-inside對Big-O無關緊要,因為它只增加了一個系數。

因此,只需乘以循環的順序: N * Log N = N Log N

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM