簡體   English   中英

這個特定函數的時間復雜度\\ big(O)是多少?

[英]What is the time complexity \big(O) of this specific function?

該函數(f1)的時間復雜度是多少?

如我所見,第一個循環(i = 0)->(n / 4次)第二個循環(i = 3)->(n / 4-3次)....等等,結果是:( n / 3)*(n / 4 +(n-3)/ 4 +(n-6)/ 4 +(n-9)/ 4 ....

我在這里停止,如何繼續?

int f1(int n){
  int s=0;
  for(int i=0; i<n; i+=3)
    for (int j=n; j>i; j-=4)
      s+=j+i;
  return s;
}

Big(O)表示法的重要之處在於它消除了“常量”。 目的是確定輸入量增長時的趨勢 ,而不必擔心特定數字。

可以將其視為在不知道x和y軸的數字范圍的圖形上確定曲線。

因此,在您的代碼中,即使您為每個循環的每次迭代都跳過了n范圍內的大多數值,這也是以恆定速率完成的。 因此,無論您實際上跳過了多少,這仍然相對於n^2縮放。

計算以下任何內容都沒有關系:

1/4 * n^2
0.0000001 * n^2
(1/4 * n)^2
(0.0000001 * n)^2
1000000 + n^2
n^2 + 10000000 * n

在Big O中,這些都等效於O(n^2) 關鍵是,一旦n 足夠大(無論大小如何),所有的低階項和常數因子在“全局”中都將變得無關緊要。

值得強調的是,這就是為什么在小投入時,您應該警惕過分依賴Big O的原因。那時候,恆定的間接費用仍然會產生很大的影響。

關鍵觀察:內部循環在步驟i執行(ni)/4次,因此在步驟ni i/4

現在將i = 3k, 3(k-1), 3(k-2), ..., 9, 6, 3, 0所有這些量求和,其中3kn之前3的最大倍數(即3k <= n < 3(k+1) ):

3k/4 + 3(k-1)/4 + ... + 6/4 + 3/4 + 0/4 = 3/4(k + (k-1) + ... + 2 + 1)
                                        = 3/4(k(k+1))/2
                                        = O(k^2)
                                        = O(n^2)

因為k <= n/3 <= k+1 ,因此k^2 <= n^2/9 <= (k+1)^2 <= 4k^2

理論上是“ O(n * n)”,但是...

如果編譯器想要對其進行優化,該怎么辦:

int f1(int n){
  int s=0;
  for(int i=0; i<n; i+=3)
    s += table[i];
  return s;
}

甚至這個:

int f1(int n){
  if(n <= 0) return 0;
  return table[n];
}

那么它也可以是“ O(n)”或“ O(1)”。

請注意,從表面上看,這種優化似乎是不切實際的(由於最壞情況下的內存成本); 但是使用足夠先進的編譯器(例如,使用“整個程序優化”來檢查所有調用者並確定n始終在某個范圍內),這是不可想象的。 以類似的方式,並非所有調用方都使用常量(例如,在功能足夠先進的編譯器可以將x = f1(123);替換為x = constant_calculated_at_compile_time )。

換一種說法; 實際上,原始函數的時間復雜度取決於該函數的使用方式以及編譯器的優劣。

暫無
暫無

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

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