1.利用二倍均值的方式进行红包的划分
package packet;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* @author zhangyu
* @Description: 利用双倍均值法进行随机计算;
* @date 2019/1/7 15:28
**/
public class GeneratePacketsByDoubleMean {
@Test
public void fun() {
Listlist = generatePacketsByDoubleMean(4, 16);
System.out.println(list);
}
// 二倍均值法
private ListgeneratePacketsByDoubleMean(int person, int money) {
Listlist = new ArrayList<>();
Random ran = new Random();
while (person > 1) {
int num = ran.nextInt(2 * (money / person));
list.add(num);
money = money - num;
person--;
}
list.add(money);
return list;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
2.一条线段上标记n-1个点,然后按照每个点剪断,就得到了随机数
package packet;
import org.junit.Test;
import java.util.*;
/**
* @author zhangyu
* @Description: 一条线段上标记n-1个点,然后按照每个点剪断,就得到了随机小数
* @date 2019/1/7 17:19
**/
public class GenerateDoublePacketsByLineCutting {
@Test
public void fun() {
// 抢红包保留两位有效数字
Listlist = generateDoublePacketsByLineCutting(4, 20);
System.out.println(list);
}
// 通过剪线算法获得红包(保留两位有效数字)
private ListgenerateDoublePacketsByLineCutting(int person, int money) {
// 定义一个treeset
Listpackets = new ArrayList<>();
Random random = new Random();
Setpoints = new TreeSet<>();
while (points.size() < person - 1) {
// 找到n-1个点
Double num = (int) Math.round(random.nextDouble() * (money - 1) * 100) / 100.0;
points.add(num);
}
// 记录最后一个点
points.add(Double.valueOf(money));
Double proPoint = 0d;
for (Double point : points) {
// 最后进行求值取差计算
Double num2 = (int) Math.round(random.nextDouble() * (point - proPoint) * 100) / 100.0;
packets.add(num2);
proPoint = point;
}
return packets;
}
}
时间复杂度:O(n)
空间复杂度:O(n)