今天面蔚来被问到了,当时实现的算法不够均匀,被面试官指出了,上网搜了下,有种二倍均值法可以实现,故在此记录
1 算法介绍
对于钱数money
,份数person
,每次计算出均值avgAmount = money / person
,再将其乘2
,得到下一个人可分配红包的范围,进行分配以后,money
和person
都减少,再进行该操作,最后一个人不用随机,直接取剩余金额即可
2 算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package test;
import java.io.IOException; import java.util.Arrays;
public class Test { public static void main(String[] args) throws IOException { int money = 100; int person = 10; int[] resultArr = clickReaPacket(money, person); String s = Arrays.toString(resultArr); System.out.println(s); }
private static int[] clickReaPacket(int money, int person) { int[] amountArr = new int[person]; System.out.printf("%s 分钱分给 %s 人\n", money, person); for (int i = 0; i < amountArr.length - 1; i++) { double avgAmount = ((double) money) / person; double doubleAvfAmount = avgAmount * 2; person --; int min = 1; double max = doubleAvfAmount; int currentAmount = getRandomBetween(min, max); amountArr[i] = currentAmount; money = money - currentAmount; System.out.printf("剩余人数:%s\t抢到:%s \t剩余金额:%s\t本次均值的二倍:%s\t金额随机范围:[%s, %s]\n", person, currentAmount, money, doubleAvfAmount, min, max); } amountArr[amountArr.length - 1] = money; return amountArr; }
private static int getRandomBetween(int a, double b) { double newScope = Math.random() * (b - a); return (int) (Math.floor(a + newScope)); } }
|