1.设计抢红包的问题
//二倍均值法
public static List<Integer> divideRedPackage(Integer totalAmount,
Integer totalPeopleNum) {
List<Integer> amountList = new ArrayList<Integer>();
//为了使用random.nextInt(Integer)方法不得不先把红包金额放大100倍,最后在main函数里面再除以100
//这样就可以保证每个人抢到的金额都可以精确到小数点后两位
Integer restAmount = totalAmount * 100;
Integer restPeopleNum = totalPeopleNum;
Random random = new Random();
for (int i = 0; i < totalPeopleNum - 1; i++) {
// 随机范围:[1,剩余人均金额的两倍),左闭右开
int amount = random.nextInt(restAmount / restPeopleNum * 2 ) ;
restAmount -= amount;
restPeopleNum--;
amountList.add(amount);
}
amountList.add(restAmount);
return amountList;
}
给定一个 0-4随机数生成器 如何生成0-6随机数并验证
参考博文1
参考博文2
其实就是使用坐标轴,先确定等概率的一些数字出来,然后对于多余的那些数,直接舍去然后重新在随机一次,就可以了
class Main{
public static void main(String[] args) {
int[] result = new int[7];
for (int i = 0; i < 50000; i++) {
int r = rand6();
result[r]++;
}
for (int i = 0; i < result.length; i++) {
System.out.println("num:" + i + " times: " + result[i]);
}
}
public static int rand4() {
//大于等于 0.0 且小于 1.0
double rand = Math.random() * 5;
return (int) rand;
}
// 0 -6 实际 7个数字
public static int rand6() {
int result = rand4() * 5 + rand4();
do {
result = rand4() * 5 + rand4();
} while (result > 20);
return result / 3;
}
}
海量数据中寻找中位数
只有2G内存的pc机,在一个存有10G个整数的文件,从中找到中位数,写一个算法。
参考博文
64匹马8个跑道需要多少轮才能选出最快的四匹?
一:计时的场景:8场,不用解释,根据计时排名
二:无计时的场景:最少10场,最多11场
1、分8组决出8个前四名,共跑8次,每个小组剩下四人;(已跑8场) 把八个小组里面的第一名选手代表小组出来跑(已跑8+1 = 9 场)
2、淘汰后四组,他们组中的第一名都没进前四,剩下的肯定不行,后四组全部淘汰
3、排名第四的组,淘汰剩下的3个,因为他们中最好的,顶多就是维持目前的第四名,剩下人不可能进前四
4、排名第三的组,淘汰四个中的三四名,因为他们中最好的,顶多维持目前的第三名,剩下的三个人中,最好的也就是此组第二名有可能挤下掉当前排名第四的马
5、排名第二的组,淘汰四个中的第四名,原理同上
6、排名第一的组,一个都不淘汰,因为这组的第一名是64匹马中最好的,已经确定了,这一组剩下的2,3,4名,可能把当前的2,3,4名挤下去
7、此时64中的第一名就是刚才代表中的第一名,然后剩下第一组的234名和第二组123名和第三组12名,和第四组1名,一共9匹, 进行比赛,要选出剩下9匹中的前三名,首先把第一组第4名移出来,剩下八匹比赛(已跑8+1+1 = 10 场),选出前三名。
8、此时选出前三名,要进行判断了:第一组的第3名如果没进8进3中的前两名,第一组第4名肯定不会超越第一组第3名,最多最多在第一组第3名背后排最终的老五,所以最快的四匹马已经找到了 但是,如果第一组的第3名进了8进3中的前两名,那最终第四名,刚才没跑的:第一组第4名,还有可能顶上去,就要把刚才的产生的8进3的第三名和刚才没跑的:第一组第4名,两匹马一起再跑一次得出最终的第四名(已跑8+1+1+1 = 11 场)
参考博文