[英]Big-O notation of an algorithm that runs max(n,0) times?
我有以下算法:
for(int i = 1; i < n; i++)
for(int j = 0; j < i; j++)
if(j % i == 0) System.out.println(i + " " + j);
這將運行max(n,0)
次。
Big-O 表示法是O(n)
嗎? 如果不是,那是什么,為什么?
謝謝你。
您還沒有說明您要使用 Big-O 表示法測量什么。 讓我們假設它的時間復雜度。 接下來,我們必須定義要衡量復雜性的因變量。 這里一個合理的選擇是n
的絕對值(與位長相反),因為您正在處理固定長度的int
而不是任意長度的整數。
您是對的println
執行 O(n) 次,但這是計算某行被命中的頻率,而不是測量時間復雜度。
很容易看出if
語句被擊中了O(n^2)
次,所以我們已經確定時間復雜度由Omega(n^2)
從下限開始。 正如評論者已經指出的那樣,if 條件僅對j=0
,所以我懷疑您實際上是想寫i % j
而不是j % i
? 這很重要,因為println(i + " " + j)
語句的時間復雜度肯定不是O(1)
,而是O(log n)
(您不可能在少於x
步的時間內打印x
字符),所以乍一看,整體復雜度有可能嚴格比O(n^2)
。
假設您打算寫i % j
我們可以簡化假設條件始終為真,在這種情況下,我們將獲得上限O(n^2 log n)
,這嚴格比O(n^2)
!
但是,請注意n
的除數的數量受O(Sqrt(n))
,我們實際上有O(n^2 + n*Sqrt(n)*log(n))
。 但由於O(Sqrt(n) * log(n)) < O(n)
,這相當於O(n^2)
。
您可以深入研究數論以找到更嚴格的除數范圍,但這並沒有什么區別,因為n^2
仍然是主導因素。
所以最嚴格的上限確實是O(n^2)
,但它並不像乍一看那樣明顯。
max(n,0)
確實是O(n)
。 但是,您的算法在O(n**2)
。 您的第一個循環進行了n
次,第二個循環進行了i
次,平均為n/2
。 這使得O(n**2 / 2) = O(n**2)
。 但是,與算法的運行時不同,達到println
的次數在O(n)
,因為這恰好發生了n
次。
因此,答案取決於您究竟要測量什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.