[英]Why is the Big-O of this algorithm N^2*log N
將數組a從[0]填充到[n-1]:生成隨機數,直到得到一個尚未包含在先前索引中的數字。
這是我的實施:
public static int[] first(int n) {
int[] a = new int[n];
int count = 0;
while (count != n) {
boolean isSame = false;
int rand = r.nextInt(n) + 1;
for (int i = 0; i < n; i++) {
if(a[i] == rand) isSame = true;
}
if (isSame == false){
a[count] = rand;
count++;
}
}
return a;
}
我以為它是N ^ 2,但它顯然是N ^ 2logN,我不確定何時考慮日志功能。
0
條目立即填寫。 1
條目的概率為1 - 1 / n = (n - 1) / n
由隨機數填充。 所以我們需要平均n / (n - 1)
隨機數來填補第二個位置。 一般來說,對於k
條目,我們需要平均n / (n - k)
隨機數,對於每個數字,我們需要進行k
比較以檢查它是否是唯一的。
所以我們需要
n * 1 /(n - 1)+ n * 2 /(n - 2)+ ... + n *(n - 1)/ 1
比較平均。 如果我們考慮總和的右半部分,我們看到這一半大於
n *(n / 2)*(1 /(n / 2)+ 1 /(n / 2 - 1)+ ... + 1/1)
已知分數之和為Θ(log(n))
因為它是一個諧波系列 。 所以總和是Ω(n^2*log(n))
。 以類似的方式,我們可以將總和顯示為O(n^2*log(n))
。 這意味着我們平均需要
Θ(N ^ 2 *的log(n))
操作。
這類似於優惠券收集器問題。 你從n個項目中挑選,直到你得到一個你還沒有的項目。 平均而言,您有O(n log n)次嘗試(請參閱鏈接,分析並非易事)。 在最壞的情況下,您會檢查每次嘗試的n個元素。 這導致平均復雜度為O(N ^ 2 log N)
你擁有的算法不是O(n^2 lg n)
因為你擁有的算法可能永遠循環而不是完成。 想象一下,在你的第一次傳球,你得到一些價值$ X $,並在每次后續傳球,試圖得到第二個值,你繼續得到$ X $永遠。 畢竟,我們在這里談論最糟糕的情況。 這將永遠循環。 所以,既然你最糟糕的情況永遠不會結束,你就無法真正分析。
如果你想知道,如果你知道n
總是數組的大小和值的上限,你可以簡單地這樣做:
int[] vals = new int[n];
for(int i = 0; i < n; i++) {
vals[i] = i;
}
// fischer yates shuffle
for(int i = n-1; i > 0; i--) {
int idx = rand.nextInt(i + 1);
int t = vals[idx];
vals[idx] = vals[i];
vals[i] = t;
}
一個循環向下,一個循環返回。 O(n)
。 簡單。
如果我沒弄錯的話,log N部分來自這部分:
for(int i = 0; i < count; i++){
if(a[i] == rand) isSame = true;
}
請注意,我將n
更改為count
因為您知道每個循環中只有數組中的count
元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.