面試題反思:隨機打亂數組順序(考察隨機數的使用)

引言

前段時間面試碰到一道題,題目主要就是隨機打亂一個數組的順序。乍一聽我以爲挺簡單的,可是到寫代碼的時候卻有種「無從下手」的感受,緣由在於本身其實以前並無使用過(也沒有仔細思考過)「隨機性」javascript

產生指定範圍的隨機數

Math.random()返回一個隨機數,均勻分佈在[0,1)範圍。用這個方法咱們能夠在任意範圍產生隨機數。
好比java

  • Math.random()*10均勻分佈在[0,10)範圍的有理數
  • Math.floor(Math.random()*10)均勻分佈在[0,9]範圍的整數(獲得0~9這10個整數的機率相同)。
  • Math.floor(Math.random()*10)+55:均勻分佈在[55,64]範圍的整數(獲得這10個整數的機率相同)。

更通常化的,產生指定範圍的隨機有理數方法:面試

// 產生一個[min,max)範圍的隨機有理數
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

產生指定範圍的隨機整數的方法:算法

// 產生一個[min,max]範圍的隨機整數,注意這個範圍包含max
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

上面這個方法中的+ 1是一個很容易遺漏的地方,考慮一下爲何Math.floor(Math.random()*10)最大隻能產生9。數組

用隨機數打亂數組

一個簡潔的辦法是,利用sort:dom

function shuffle(array) {
    array.sort(function() {
        return 0.5 - Math.random();
    });
}

可是這種方法並不能作到真正的「均勻打亂」,能夠看看參考資料3中的知乎討論。
這位答主結合生動的圖片解釋了更好的均勻打亂算法:Fisher–Yates shuffle。code

function shuffle(array) {
    var m = array.length,
        t, i;
    while (m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
    }
    return array;
}

這裏就不盜人家的圖了,讀者能夠點擊連接查看。
這個簡潔的算法不難理解,主要的步驟是i = Math.floor(Math.random() * m--),這個語句先獲取一個[0,m-1]範圍的隨機下標賦值給i,而後m=m-1圖片

參考資料

  1. https://stackoverflow.com/que...
  2. https://stackoverflow.com/que...
  3. https://www.zhihu.com/questio...
相關文章
相關標籤/搜索