470. 用 Rand7() 实现 Rand10()

思路:

1、用Rand10()实现Rand7()比较容易(大数实现小数):

第一次就命中的p:7/10

第二次命中的p:3/10+7/10

第三次命中的p:\frac{3}{10}^{^{^{^{^{2}}}}}+\frac{7}{10}

以此类推:根据等比数列公式得出:

2、用Rand7()实现Rand10()(小数实现大数):

将小数映射为大数,并且要求在区间[x,y]内得数都能等概率获得

(RandX()-1)*X+RandY()可以等概率获得区间[1,X*Y]内的数

3、现在只有Rand7(),则第一步:(Rand7()-1)*7+Rand7()得到[1,49]内的某个数

如果是[41,49]间的数,再次进行大数映射:(num-40-1)*7+Rand7()可以得到[1,63]间的某个数

如果是[61,63]间的数,再次进行大数映射:(num-60-1)*7+Rand7()可以得到[1,21]间的某个数

如果是21则直接舍弃,这样就只需要舍弃一个数

代码:

class Solution extends SolBase {
    public int rand10() {
        while(true){
			//映射到大数[1,49]
			int num = (rand7()-1)*7+rand7();
			if(num<=40){
				//预防出现10、20、30、40的情况
				return num%10+1;
			} else {
				//从41~49中选,重新映射到大数[1,63]
				num = (num-40-1)*7+rand7();
				if(num<=60){
					return num%10+1;
				} else {
					//从61~63中选,重新映射到大数[1,21],只需要舍弃一个数
					num = (num-60-1)*7+rand7();
					if(num<=20){
						return num%10+1;
					}
					//否则舍弃21,重新进入循环,这样时间会显著减少   
				}
			}
		}
    }
}

分解:

1、在[1,49]情况下,如果是[1,40],可以通过与10取模+1,来获取10以内的数

+1是防止出现整数10、20、30、40的情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值