如何实现抢红包算法?
方法一:二倍均值法
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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)