簡體   English   中英

為什么這個算法的Big-O N ^ 2 * log N.

[英]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.

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