日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现抢红包算法?如此简单

發(fā)布時間:2023/12/31 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现抢红包算法?如此简单 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.











發(fā)出一個固定金額的紅包,由若干個人來搶,需要滿足哪些規(guī)則?


1.所有人搶到金額之和等于紅包金額,不能超過,也不能少于。


2.每個人至少搶到一分錢。


3.要保證所有人搶到金額的幾率相等。





小灰的思路是什么樣呢?


每次搶到的金額 = 隨機區(qū)間?( 0,? 剩余金額 )





為什么這么說呢?讓我們看一個栗子:


假設有10個人,紅包總額100元。


第一個人的隨機范圍是(0,100元),平均可以搶到50元


假設第一個人隨機到50元,那么剩余金額是100-50 = 50 元。


第二個人的隨機范圍是?(0, 50元),平均可以搶到25元


假設第二個人隨機到25元,那么剩余金額是50-25 = 25 元。


第三個人的隨機范圍是?(0, 25元),平均可以搶到12.5元


以此類推,每一次隨機范圍越來越小。







方法1:二倍均值法


剩余紅包金額為M,剩余人數(shù)為N,那么有如下公式:


每次搶到的金額 = 隨機區(qū)間?(0, M / N X 2)


這個公式,保證了每次隨機金額的平均值是相等的,不會因為搶紅包的先后順序而造成不公平。


舉個栗子:


假設有10個人,紅包總額100元。


100/10X2 = 20, 所以第一個人的隨機范圍是(0,20 ),平均可以搶到10元


假設第一個人隨機到10元,那么剩余金額是100-10 = 90 元。


90/9X2 = 20, 所以第二個人的隨機范圍同樣是(0,20 ),平均可以搶到10元


假設第二個人隨機到10元,那么剩余金額是90-10 = 80 元。


80/8X2 = 20, 所以第三個人的隨機范圍同樣是(0,20 ),平均可以搶到10元


以此類推,每一次隨機范圍的均值是相等的。





  • //發(fā)紅包算法,金額參數(shù)以分為單位

  • public static List<Integer> divideRedPackage(Integer totalAmount, Integer totalPeopleNum){

  • ? ?List<Integer> amountList = new ArrayList<Integer>();

  • ? ?Integer restAmount = totalAmount;

  • ? ?Integer restPeopleNum = totalPeopleNum;

  • ? ?Random random = new Random();

  • ? ?for(int i=0; i<totalPeopleNum-1; i++){

  • ? ? ? ?//隨機范圍:[1,剩余人均金額的兩倍),左閉右開

  • ? ? ? ?int amount = random.nextInt(restAmount / restPeopleNum * 2 - 1) + 1;

  • ? ? ? ?restAmount -= amount;

  • ? ? ? ?restPeopleNum --;

  • ? ? ? ?amountList.add(amount);

  • ? ?}

  • ? ?amountList.add(restAmount);

  • ? ?return amountList;

  • }

  • public static void main(String[] args){

  • ? ?List<Integer> amountList = divideRedPackage(5000, 30);

  • ? ?for(Integer amount : amountList){

  • ? ? ? ?System.out.println("搶到金額:" + new BigDecimal(amount).divide(new BigDecimal(100)));

  • ? ?}

  • }


  • 程序輸出結(jié)果如下:

    搶到金額:2.92

    搶到金額:1.48

    搶到金額:3.05

    搶到金額:0.53

    搶到金額:0.45

    搶到金額:1.36

    搶到金額:1.02

    搶到金額:1.99

    搶到金額:1.3

    搶到金額:0.48

    搶到金額:0.83

    搶到金額:2.89

    搶到金額:0.94

    搶到金額:2.11

    搶到金額:3.13

    搶到金額:0.91

    搶到金額:2.64

    搶到金額:2.02

    搶到金額:2.88

    搶到金額:1.13

    搶到金額:2.09

    搶到金額:1.37

    搶到金額:2.41

    搶到金額:2.13

    搶到金額:1.32

    搶到金額:0.44

    搶到金額:1.62

    搶到金額:1.89

    搶到金額:2.23

    搶到金額:0.44










    方法2:線段切割法


    何謂線段切割法?我們可以把紅包總金額想象成一條很長的線段,而每個人搶到的金額,則是這條主線段所拆分出的若干子線段。





    如何確定每一條子線段的長度呢?由“切割點”來決定。當N個人一起搶紅包的時候,就需要確定N-1個切割點。


    因此,當N個人一起搶總金額為M的紅包時,我們需要做N-1次隨機運算,以此確定N-1個切割點。隨機的范圍區(qū)間是(1, M)。


    當所有切割點確定以后,子線段的長度也隨之確定。這樣每個人來搶紅包的時候,只需要順次領取與子線段長度等價的紅包金額即可。


    這就是線段切割法的思路。在這里需要注意以下兩點:


    1.當隨機切割點出現(xiàn)重復,如何處理。

    2.如何盡可能降低時間復雜度和空間復雜度。








    —————END—————

    總結(jié)

    以上是生活随笔為你收集整理的实现抢红包算法?如此简单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。