面試問題:發一個隨機紅包,100塊錢給10我的。每一個人最多12塊錢,最少6塊錢。怎麼分?

這問題是@xinhaip從那邊看來。
他以前的思路是這樣子:php

之前想過一個相似問題,就是沒有每一個人最大、最小的得錢數的限制,之前的問題能夠很好用隨機數解決。面試

因而這個問題也被之前的思想帶坑裏了,把突破口徹底放在瞭如何處理每一個人的隨機數上。segmentfault

因而在面試時間就沒有解決這個問題,直到面試結束本身安靜下來,仔細想一想,發現思路錯了。函數

在我看來其實他一開始的思路偏偏是正確的,然而我在他的問題下面發佈了答案,卻沒什麼人贊同。
我只能在本身寫個文章分析下個人解題思路。code

題目

發一個隨機紅包,100塊錢給10我的。每一個人最多12塊錢,最少6塊錢。怎麼分?ip

答案

sum=100n=10,則題目能夠獲得如下結論6n <= sum <= 12nget

randNum爲隨機紅包的大小,則能夠推出6(n-1) <= (sum-randNum) <= 12(n-1)it

從上面的結論裏咱們能夠獲得如下答案io

function makeSeq(){
    $n = 10;
    $sum = 100;
    $result = [];
    while ($n > 1) {
        // 6n <= sum <=12n
        $randNum = mt_rand(600,1200) / 100;
        if(($sum-$randNum) >= 6* ($n - 1) && ($sum-$randNum) <= 12* ($n - 1)){
            $sum -= $randNum;
            $n -= 1;
            $result[] = $randNum;
        }
    }
    $result[] = $sum;
    return $result;
}

進階

上面的答案效率不是很高,其實咱們能夠經過計算紅包的上下界,而後經過一次隨機獲得答案。
6(n-1) <= (sum-randNum) <= 12(n-1)可得sum - 12(n-1) <= randNum <= sum - 6(n-1)
又由6 <= randNum <= 12計算獲得紅包的上下界:function

$min = ($sum - 12 * ($i-1))>6?($sum - 12 * ($i-1)):6;
 $max = ($sum - 6 * ($i-1))<12?($sum - 6 * ($i-1)):12;

則最終答案是

function makeSeq2(){
    $n = 10;
    $sum = 100;
    $result = [];
    for($i=$n;$i>=1;$i--){
        $min = ($sum - 12 * ($i-1))>6?($sum - 12 * ($i-1)):6;
        $max = ($sum - 6 * ($i-1))<12?($sum - 6 * ($i-1)):12;
        $randNum = mt_rand($min,$max);
        $sum -= $randNum;
        $result[] = $randNum;
    }
    return $result;
}

根據種子生成序列,且符合指望

評論裏說生成的序列不符合平均爲10的指望,因此咱們須要在返回結果結果前打亂序列。
最好還能根據種子生成每次都相同的結果,在這裏咱們要自定義shuffle函數。

function myShuffle(&$items,$seed) { 
    mt_srand($seed); 
    for ($i = count($items) - 1; $i > 0; $i--){ 
        $j = @mt_rand(0, $i); 
        $tmp = $items[$i]; 
        $items[$i] = $items[$j]; 
        $items[$j] = $tmp; 
    } 
} 

function makeSeq2($seed){
    mt_srand($seed);
    $n = 10;
    $sum = 100;
    $result = [];
    for($i=$n;$i>=1;$i--){
        $min = ($sum - 12 * ($i-1))>6?($sum - 12 * ($i-1)):6;
        $max = ($sum - 6 * ($i-1))<12?($sum - 6 * ($i-1)):12;
        $randNum = mt_rand($min,$max);
        $sum -= $randNum;
        $result[] = $randNum;
    }
    myShuffle($result,$seed);
    return $result;
}
相關文章
相關標籤/搜索