如何实现抢红包算法?

方法一:二倍均值法

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;
    }

缺陷:除了最后一次,任何一次抢到的金额都不会超过人均金额的两倍,并不是任意的随机

方法二: 线段分割法

实现真正的随机

思路:

①,待分割的数为n,有m个人抢红包,可以随机插入m-1块板,则能将n分成m份

②,将分好组的数进行排序,取出放到list中,则能随机分成m个红包

public static void line_cut(int money,int people ) {
        List<Integer> team=new ArrayList<>();
        List<Integer> result=new ArrayList<>();
        ThreadLocalRandom random=ThreadLocalRandom.current();
        
        int m=money-1;
        while(team.size() < people -1) {
            int nextInt = random.nextInt(m)+1;//不让nextInt 为0
            if(!team.contains(nextInt)) {
                team.add(nextInt);
            }            
        }
        Collections.sort(team);
        System.out.println(team);
       
        for (int i = 0; i < team.size(); i++) {
            if(i== 0) {
                result.add(team.get(i));
            }else {
                result.add(team.get(i)-team.get(i-1));
                if(i==team.size()-1) {
                    result.add(money-team.get(i));
                }
            }
        }
        System.out.println(result);        
        //验证分割后的数是否是输入的总金额
        Optional<Integer> r = result.stream().reduce(Integer::sum);
        System.out.println(r.get());
    }

 

 

 

 推荐阅读

https://blog.csdn.net/bjweimengshu/article/details/80045958

转载于:https://www.cnblogs.com/dongma/p/10077901.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值