洗牌演算法是什麼?
其實就理解為生成乙個隨機數列的乙個簡單操作而已。
怎麼生成?
我們先講下一般我們會想到的乙個解法——標記。
怎麼標記呢?
假設我們的陣列為a,ai 代表陣列a第i個數。
乙個布林陣列b(其他型別的陣列也行)。
然後把a陣列下標作為狀態空間進行隨機生成,接著把生成過的數下標 i 用 bi =1表示為已出現過,用 bi==0表示為未出現過.
如果前面出現過的數則重新隨機。
問題來了:這樣的複雜度是多少?——會是n2的複雜度,如果平均下來也是n log n
所以怎麼處理這個問題?
如果你想刪除當前數的話——刪除會導致陣列整體向後移動啊!
相信大家都學過二叉堆(沒學過也沒事),更新數值時我們會把堆頂放在堆末尾,然後再up,down操作一遍。
模擬一下——這樣避免了整個陣列的往後移動。
假設最初陣列裡1~n個數需要隨機,目前隨機範圍為n
所以我們可以生成完當前數後,把這個數和最後乙個數交換,然後隨機下標範圍變為n-1
以此迴圈即可。
隨機洗牌演算法
問題 給定乙個有序序列1 n,要你將其完全打亂,要求每個元素在任何乙個位置出現的概率均為1 n。解決方案 依次遍歷陣列,對第n個元素,以1 n的概率與前n個元素中的某個元素互換位置,最後生成的序列即滿足要求,1 n的概率可通過rand n實現。見如下程式 void swap int p,int q ...
隨機洗牌演算法
先看看肖舸老師的文章 隨機洗牌演算法複雜度的比較例項 其實我最初想到的也是那3個方法 1判斷生成的隨機數有沒有重複,2.生成一張布林表,3.雙隨機數。下面給出我的演算法 include include include using namespace std void randcard vector,...
陣列中隨機抽取 演算法 撲克隨機洗牌演算法分析
洗牌演算法實際上就是常見的隨機問題。我們可以抽象理解為 得到乙個m以內的所有自然數的隨機順序陣列。然而怎麼樣操作才是好的洗牌演算法呢?我們通常認為得保證概率相等。即洗牌之後,如果能夠保證每乙個數出現在所有位置上的概率是相等的。隨機抽出一張牌 檢查這種牌是否被抽取過,如果已經被抽取過,則重新抽取,直到...