抢红包算法

1,815 阅读1分钟

二倍均值法

假设人数为 N,钱数为 M,且都为整数。每次分配的红包为 [0, 2*M/N] 之间的某个随机数,那么分配的红包数额的均值为 M/N。
该算法可以保证每次分配的红包均值都为 M/N,但是并不能保证每个红包的均值都一样,因为 M 和 N 一直在变化,那么 M/N 的值就会不同。

N M 红包
5 10 2
4 8 2
3 6 2
2 4 2
1 2 2
List<Integer> generatePacketsByDoubleMean(int people, int money) {
List<Integer> packets = new ArrayList<>();
Random random = new Random();
while (people > 1) {
int p = random.nextInt(2 * money / people);
packets.add(p);
money -= p;
people--;
}
packets.add(money);
return packets;
}

线段切割法

在一条线段上找 N-1 个随机点,就可以将该线段随机且公平地切割成 N 段。

List<Integer> generatePacketsByLineCutting(int people, int money) {
List<Integer> packets = new ArrayList<>();
Random random = new Random();
Set<Integer> points = new TreeSet<>();
while (points.size() < people - 1) {
points.add(random.nextInt(money - 1));
}
points.add(money);
int pre = 0;
for (int p : points) {
packets.add(p - pre);
pre = p;
}
return packets;
}

参考资料