作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/implement-rand10-using-rand7/description/

题目描述

Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a function rand10 which generates a uniform random integer in the range 1 to 10.

Do NOT use system’s Math.random().

Example 1:

Input: 1
Output: [7]

Example 2:

Input: 2
Output: [8,4]

Example 3:

Input: 3
Output: [8,1,10]

Note:

  1. rand7 is predefined.
  2. Each testcase has one argument: n, the number of times that rand10 is called.

Follow up:

  1. What is the expected value for the number of calls to rand7() function?
  2. Could you minimize the number of calls to rand7()?

题目大意

利用一个范围在1~7的随机数产生器,构造一个范围在1~10的随机数产生器。

解题方法

范围在1~7的随机数产生器,即1~7各个数字出现的概率皆为1/7.
范围在1~10的随机数产生器,即1~10各个数字出现的概率皆为1/10.

这个题的构造思路是先构造一个randN,这个N必须是10的整数倍,然后randN % 10就可以得到了rand10.

所以可以从rand7先构造出rand49,再把rand49中大于等于40的都过滤掉,这样就得到了rand40,在对10取余即可。

具体一点就是:

  1. rand7()等概率地产生1,2,3,4,5,6,7.
  2. rand7() - 1等概率地产生[0,6].
  3. (rand7() - 1) *7等概率地产生0, 7, 14, 21, 28, 35, 42
  4. (rand7() - 1) * 7 + (rand7() - 1)等概率地产生[0, 48]这49个数字
  5. 如果步骤4的结果大于等于40,那么就重复步骤4,直到产生的数小于40
  6. 把步骤5的结果mod 10 再加1, 就会等概率的随机生成[1, 10]

所以过程是:

rand7 --> rand49 --> rand40 --> rand10.

其中,构造rand49的方式是:

7 * (rand7() - 1) + rand7() - 1

那么,如何理解呢?上面的做法到底如果理解才能记住呢?看下面这个表格:


看上面的表格,可以这么理解:我们先产生[1,49]之间的随机正整数,构建的方式是扔两次rand7()两次的结果分别作为表格的行和列,因此,7 * (rand7() - 1) + rand7()的取值范围是[1, 49],代表上面表格的任意位置。注意,我们需要把上图黄色部分的给过滤掉,因为这9个数字超出了40的范围,即如果两次扔rand7()产生的数字在上面黄色的部分需要重新扔。得到了[1,49]之后,然后减去1 再 mod 10 再加1即可。

这个方法我觉得最好要记住。

# The rand7() API is already defined for you.
# def rand7():
# @return a random integer in the range 1 to 7 class Solution:
def rand10(self):
"""
:rtype: int
"""
return self.rand40() % 10 + 1 def rand49(self):
"""
random integer in 0 ~ 48
"""
return 7 * (rand7() - 1) + rand7() - 1 def rand40(self):
"""
random integer in 0 ~ 40
"""
num = self.rand49()
while num >= 40:
num = self.rand49()
return num

C++代码如下:

// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7 class Solution {
public:
int rand10() {
return rand40() % 10 + 1;
} int rand49() {
return (rand7() - 1) * 7 + (rand7() - 1);
} int rand40() {
int r = rand49();
while (r >= 40) {
r = rand49();
}
return r;
}
};

日期

2018 年 8 月 18 日 —— 天在下雨
2019 年 1 月 23 日 —— 又一连过去了几天

【LeetCode】470. Implement Rand10() Using Rand7() 解题报告(Python & C++)的更多相关文章

  1. [LeetCode] 470. Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...

  2. LC 470. Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...

  3. 470. Implement Rand10() Using Rand7() (拒绝采样Reject Sampling)

    1. 问题 已提供一个Rand7()的API可以随机生成1到7的数字,使用Rand7实现Rand10,Rand10可以随机生成1到10的数字. 2. 思路 简单说: (1)通过(Rand N - 1) ...

  4. 【LeetCode】206. Reverse Linked List 解题报告(Python&C++&java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 [LeetCode] 题目地址:h ...

  5. 【LeetCode】654. Maximum Binary Tree 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

  6. 【LeetCode】784. Letter Case Permutation 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 循环 日期 题目地址:https://leet ...

  7. 【LeetCode】731. My Calendar II 解题报告(Python)

    [LeetCode]731. My Calendar II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题 ...

  8. 【LeetCode】732. My Calendar III解题报告

    [LeetCode]732. My Calendar III解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/my-calendar ...

  9. 【LeetCode】729. My Calendar I 解题报告

    [LeetCode]729. My Calendar I 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/my-calendar- ...

随机推荐

  1. Python基础之变量与常量

    目录 1. 变量 1.1 变量的定义和组成 1.2 变量名的命名规则 1.3 变量名的两种风格 2. 常量 3. 变量内存管理 3.1 变量的存储 3.2 垃圾回收机制 3.2.1 引用计数 3.3 ...

  2. SM 国密算法踩坑指南

    各位,好久不见~ 最近接手网联的国密改造项目,由于对国密算法比较陌生,前期碰到了一系列国密算法加解密的问题. 所以这次总结一下,分享这个过程遇到的问题,希望帮到大家. 国密 什么是国密算法? 国密就是 ...

  3. Qemu/kvm虚拟化源码解析学习视频资料

    地址链接:tao宝搜索:Linux云计算KVM Qemu虚拟化视频源码讲解+实践​https://item.taobao.com/item.htm?ft=t&id=646300730262 L ...

  4. 日常Java 2021/11/9

    线程的优先级 每一个Java线程都有一个优先级,这样有助于操作系统确定线程的调度顺序.Java线程的优先级是一个整数,其取值范围是1(Thread.MIN_PRIORITY ) -10 (Thread ...

  5. Linux 设置时区

    一.查看和修改Linux的时区 1. 查看当前时区命令 : "date -R" 2. 修改设置Linux服务器时区方法 A命令 : "tzselect" 方法 ...

  6. Fragment放置后台很久(Home键退出很长时间),返回时出现Fragment重叠解决方案

    后来在google查到相关资料,原因是:当Fragment长久不使用,系统进行回收,FragmentActivity调用onSaveInstanceState保存Fragment对象.很长时间后,再次 ...

  7. Windows zip版本安装MySQL

    Windows --MySQL zip版本安装记录: step1. 官网download zip包:http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5. ...

  8. 使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量数据快速导入导出

    使用MySQL的SELECT INTO OUTFILE .Load data file LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.当用户一前一后地使用SELECT ...

  9. alert之后才执行

    如果在正常情况下,代码要在alert之后才执行,解决办法:将要执行的代码用setTimeout延迟执行即可(原因:页面未加载完毕)

  10. 【Linux】【Shell】【Basic】Programming

    shell脚本编程: 编程语言的分类:根据运行方式 编译运行:源代码-->编译器(编译)-->程序文件 解释运行:源代码-->运行时启动解释器,又解释器边解释边运行 根据其编程过程中 ...