方法一:二倍均值法
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