用rand7生成rand10

1. 解法

1.描述:

  1. 先用`(rand7()-1)*7+rand7()`来构造rand49,
  2. 舍去[41-49]的case,剩下rand40
  3. rand10 = rand40%10 + 1

2.代码描述

    // java
    public int rand10() {
        int rand40 = 40;
        while (rand40 >= 40) {
            rand40 = (rand7() - 1) * 7 + rand7() - 1;
        }
        return rand40 % 10 + 1;
    }

2.解法分析(本文重点)

2.1 如何构造rand49

        首先看两个反例

        反例1: rand[2-14] = rand7() * 2 

        rand7() * 2构造出来的是rand[2,4,6,8,10,12,14],而不是rand[2-14],因为3,5,7,9,11,13,这几个case都不会出现

        反例2:rand[2-14] = rand7() + rand7()

        这里就不能像反例1中来解释了,这里必须用概率论来解释。首先左边rand[2-14]表示[2,3,4,5,6,7,8,9,10,11,12,13,14]这些数字出现的概率是相等的,都是1/13。但是rand7() + rand7()组成的case中却不是。

        用Pi表示左边rand[2-14]元素i的概率,用pi表示rand7中每一个元素i的概率。比如

  1. P2 = p1*p1,
  2. P3=p1*p2 + p2*p1 = 2/49, 所以很显然P2!=P3。同理可以继续计算
  3. P4=p1*p3 + p2*p2 + p3*p1 = 3/49,所以 P2!=P3!=P4。

        所以rand[2-14] != rand7() + rand7()

        那么 rand49 = (rand7()-1)*7+rand7() 成立吗?成立的。这里不做证明,简单描述一下, (rand7()-1)*7 是把rand7放大7倍,也就是变成了 [0,7,14,21,28,35,42],再用rand7()来填补0-7、7-14、14-21、21-28、28-35、35-42之间的空缺,所以P1=P2=P3=...=P49的

2.2 为什么就能舍去[41-49]的case

        一句话,因为P1=P2=P3=...P47=P48=P49 = 1/49。舍去其中的任意个case,剩下的一样也是概率相等的——概率不在是1/49。

2.3 rand10 = rand40%10 + 1

        %10可以,/4就不行吗?其实都是可以的,都是在1-40的case中映射出10个case,而且都是这种映射是不会造成结果概率不等的。

        直接舍去[10-49]可以吗?可以的,功能可以实现,但是性能大打折扣,折扣为原来的1/4。因为%10时,可用case是40个;而舍去[10-49]则可用case为10个。(第2次编辑加)        

2.4 举一反三

        我们不但能构造出rand10,也能构造出很多小于49的random(random2、random3、...、random49)。

3.总结

1.强行让自己回忆了一下概率论和多rand的认知。

2.leetcode题目链接解法的出处 (该贴还有进阶版解法2)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值