leetcode 470. 用 Rand7() 实现 Rand10() (数学,优化策略)
题目链接
https://leetcode-cn.com/problems/implement-rand10-using-rand7/
题意:
给定一个rand7()的生成器,求解如何产生一个rand10()的生成器。注意这里定义rand7()的范围是17,而不是06
思路:
关键在于产生的结果必须是等概率的,这是一类非常泛化的题。具体而言涉及到由任意的randm()转化到randn()的计算方式。
详细解读可以参考:https://blog.csdn.net/u010025211/article/details/49668017
在这里我们假设m>n,比如由rand7()转化到rand3()
那么我们只需要把大于3的倍数的值先舍去,比如
int rand3() {
int x=INT_MAX;
while(x>6){
x=rand7();
}
return x%3+1;
}
分析一下产生1~6的概率,那么1/7+1/7*1/7+(1/7)2*1/7+...+(1/7)n*1/7=1/6
而从1~6一共产生的数为1,2,3,4,5,6每个数字出现的概率相同,所以利用x%3+1可以转化得到1,2,3的出现概率也相同
考虑一般化的情况,如果m>n那么randm转化为randn的方式可以理解为:
int rand_n(){
//m>n
int d=m/n;
int ans=INT_MAX;
while(ans>n*d){//最靠近m的整数
ans=rand_m();
}
return ans%n+1;
}
同理如果m<n时,比如rand7()转移到rand10(),这时候需要等距离覆盖,比如如果直接用两个rand7()相加得到[2,14]之间所有数字的和,但是显然这个区间每个数字出现的次数的概率不是相同的(两边出现的概率小,中间出现的概率大),那么怎么才能生成等概率,却又能覆盖掉10以类的所有数字呢?
这里采用一种映射:7*(rand7()-1)+rand7(),前面rand7()-1映射到[0,6],每个数字等概率,7*(rand7()-1)映射到[0,7,14,21,28,35,42],每个数字等概率,后面映射到[1,2,3,4,5,6,7]每个数字等概率,那么两者得到的和[1,2,3,4,5,6,7,8,9,...,42]之间出现的每个数字都是等概率的,即:rand42()=7*(rand7()-1)+rand7()
然后再从rand42()映射回来rand10()就可以了
class Solution {
public:
int randn() {
int x=INT_MAX;
// while(x>10){ //这里还可以再优化
while(x>40){
x=7*(rand7()-1)+rand7();//rand42()
// if(x<=10){
// brmeak;
// }
}
return x%10+1;
}
};
同理可以推出更普遍的情况,如果m<n,那么由rand_m()映射到rand_n()可以为:
int rand_n(){
//m<n
//假设m^k>=n && m^(k-1)<n
int k=0;
int mul=0;
while(m<n){
mul*=m;
k++;
}
int ans=INT_MAX;
while(ans>(mul/n)*n){
int tmp=rand_m();
for(int i=1;i<=k;i++){
tmp=m*(tmp-1)+rand_m(); //rand2*m
}
ans=tmp;
}
return ans%n+1;
}
leetcode 470. 用 Rand7() 实现 Rand10() (数学,优化策略)的更多相关文章
- Java实现 LeetCode 470 用 Rand7() 实现 Rand10()
470. 用 Rand7() 实现 Rand10() 已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数. 不要使用系 ...
- LeetCode 470. 用 Rand7() 实现 Rand10()(Implement Rand10() Using Rand7())
题目描述 已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数. 不要使用系统的 Math.random() 方法. 示 ...
- 470. 用 Rand7() 实现 Rand10()
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数. public class Solution { public s ...
- 随机数范围扩展(如rand7()到rand10())(转)
题目:已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10.分析:要保证rand10()在整数1-10的均匀分布,可以构造一个1-10*n的均 ...
- rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
这种题要分两步,第一步是“插空儿”,第二步是“筛” 1.rand7生成rand10 只要是10的倍数就好 int rand10() { int num; do{ num = (rand7() - ) ...
- 利用rand7()构造rand10()
题意 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10 参考代码 int rand7() { srand((int)time(NULL)) ...
- 利用rand7() 产生rand10()(腾讯)
题目1:已知rand7() 可以产生 1~7 的7个数(均匀概率),利用rand7() 产生rand10() 1~10(均匀概率) int rand10() { int temp; int te ...
- 图解Leetcode组合总和系列——回溯(剪枝优化)+动态规划
Leetcode组合总和系列--回溯(剪枝优化)+动态规划 组合总和 I 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ...
- mysql索引之四:复合索引之最左前缀原理,索引选择性,索引优化策略之前缀索引
高效使用索引的首要条件是知道什么样的查询会使用到索引,这个问题和B+Tree中的“最左前缀原理”有关,下面通过例子说明最左前缀原理. 一.最左前缀索引 这里先说一下联合索引的概念.MySQL中的索引可 ...
随机推荐
- git+pycharm结合使用
Pycharm + git 进行结合使用 第一步:Pycharm配置本地安装的Git 测试框架的负责人: 编写好一套能用的基础框架代码 --- > 上传到公司远程仓库 --- 设置团队协作成员 ...
- 【Pyhton 】 装饰器
# -*- coding:utf8 -*-# Author : Mr·Yang''' 装饰器,带参数装饰器,装饰器中带参数''' import time# 普通装饰器'''def time_decor ...
- ORACLE启用非默认监听端口
1.修改listener.ora文件 LISTENER_TEST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP ...
- 腾讯游戏 K8s 应用实践|更贴近业务场景的 K8s 工作负载:GameDeployment & GameStatefulSet
引言 蓝鲸容器服务(Blueking Container Service,以下简称BCS)是腾讯 IEG 互动娱乐事业群的容器上云平台,底层基于腾讯云容器服务(Tencent Kubernetes E ...
- ACL 的功能、匹配原则、端口号类别
功能 1)限制网络流量.提高网络性能.例如,ACL可以根据数据包的协议,指定这种类型的数据包具有更高的优先级,同等情况下可预先被网络设备处理. 2)提供对通信流量的控制手段. 3)提供网络访问的基本安 ...
- (转) SQL 中的 NULL 你真的懂了吗?【数据库|SQL】
注:转载自下面链接 https://blog.csdn.net/lnotime/article/details/104847946 SQL 中的 NULL (译自 NULL Values in SQL ...
- 07-flask-使用sqlalchemy
代码 from flask import Flask, render_template from sqlalchemy import create_engine from sqlalchemy.ext ...
- Missing Private key解决方案——IOS证书 .cer 以p12文件以及配置方案
一个苹果证书怎么多次使用--导出p12文件 为什么要导出.p12文件 因为苹果规定 .cer证书只能存在于一台机器上,因此 如果另一台电脑想要用的话,需要导出为.p12 file ,安装到另一台没有安 ...
- MySQL中的 ”SELECT FOR UPDATE“ 一次实践
背景 最近工作中遇到一个问题,两个不同的线程会对数据库里的一条数据做修改,如果不加锁的话,会得到错误的结果. 就用了MySQL中for update 这种方式来实现 本文主要测试主键.唯一索引和普通索 ...
- kali2020.01修改root终端颜色
kali2020.01非root用户的终端和root用户终端颜色存在较大差异: 修改配置,将非root用户的配置替换root用户,输入以下命令即可: cd /home/lijingrong //切换到 ...