前N個自然數的隨機置換

2022-01-31 21:49:46 字數 1229 閱讀 8622

來自:【資料結構與演算法分析——c語言描述】練習2.7

問題描述:假設需要生成前n個自然數的乙個隨機置換。例如, 和 就是合法的置換,但 卻不是,因為數1出現了兩次而數 3 缺沒有。這個程式常常用於模擬一些演算法。我們假設存在乙個隨機數生成器 randint(i, j) ,它以相同的概率生成 i 和 j 之間的乙個整數。

下面是三個演算法:

1.如下填入 a[0] 到 a[n-1] 的陣列 a;為了填入 a[i] ,生成隨機數直到它不同於已經生成的 a[0], a[1],  ... ,  a[i-1] 時,再將其填入 a[i] 。

2.同演算法1,但是要儲存乙個附加的陣列,稱之為 used(用過的)陣列。當乙個隨機數 ran 最初被放入陣列a的時候,置used[ran]=1。這就是說,當用乙個隨機數填入 a[i] 時,可以用一步來測試是否該隨機數已經被使用,而不是像第乙個演算法那樣(可能)進行 i 步測試。

3.填寫該陣列使得 a[i] = i + 1。然後

for(i = 1; i < n; i++) 

swap(&a[i], &a[randint(0, i)]);

題目中有說「我們假設存在乙個隨機數randint(i, j)」,既然如此,暫時不必考慮其內部實現以及記憶體限制,只根據這個介面考慮演算法即可。

演算法1

i = 0;

while (i < n)

if (k == i)

}

以迴圈次數作為時間度量。迴圈從i=0到i=n-1寫出n個不重複隨機數,因為生成第i個不重複隨機數的概率是(n-i)/n,所以理論上經過n/(n-i)次生成,得到不重複隨機數的概率為1。所以總耗時為

這裡做了分子的放大,以及這個調和和公式:

該演算法的時間複雜度即為o(n2logn)。

演算法2

i = 0;

while (i < n)

}

演算法 2 比演算法 1 少了內層的 for 迴圈,所以時間複雜度降了一階,即為 o(nlogn)。

演算法3

for (i = 0; i < n; i++)

a[i] = i + 1;

for (i = 0; i < n; i++)

swap(&a[i], &a[randint(0, i)]);

時間複雜度顯然是線性級的,o(n)。

生成前N個自然數隨機置換的3個程式

假設需要生成前n個自然數的乙個隨機置換。例如,和就是合法的置換,但卻不是,因為數1出現兩次而數3卻沒有。這個程式常常用於模擬一些演算法。我們假設存在乙個隨機數生成器randint i,j 它以相同的概率生成i和j之間的乙個整數。int randint int i,int j srand 放在主函式中...

歸納策略 求前n個自然數的平方之和

求前n個自然數的平方之和 s 1 2 2 2 3 2 n 2 因為 1 2 2 2 3 2 n2 1 2 3 n 2n 1 3 又由於 1 2 3 n n n 1 2,因此得到 1 2 2 2 3 2 n 2 n n 1 2n 1 6 推導過程 有乙個三角形的數字矩陣 12 2 3 3 3 4 4 ...

1757找i個連續自然數累加為N

找i個連續自然數累加為n time limit 2 seconds memory limit 32768 k total submit 391 accepted 260 description 輸入乙個數字n,找出i個連續自然數累加為n的所有和式 i 1 input 整數n output n i個連...