leetcode_470. 用 Rand7() 实现 Rand10()
目录:
用 Rand7() 实现 Rand10()
题目
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random() 方法。
示例 1: 输入: 1 输出: [7] 示例 2: 输入: 2 输出: [8,4] 示例 3: 输入: 3 输出: [8,1,10]
提示:
rand7 已定义。 传入参数: n 表示 rand10 的调用次数。
进阶:
rand7()
调用次数的 期望值 是多少 ?- 你能否尽量少调用
rand7()
?来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/implement-rand10-using-rand7 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
舍弃法
-
一次 rand7() 生成的是 1~7 的 等概率数字
-
两次 rand7() 生成的是 1~49 的 等概率数字
-
舍弃 41 ~ 49 的情况,继续生成,直到 1 ~ 40, 对10取余数 +1 即可得到等概率的 1~10
优化
生成 41 ~ 49 的时候也可以接受,即在1~9基础上再 rand7(),生成1~63
- 1 ~ 60 对10取余数 +1 即可得到等概率的 1~10
- 61 ~ 63 (1~3) 再 rand7() ,范围是 1 ~ 21,这时候直接丢弃1吧
解答
func rand10() int {
index := (rand7()-1)*7 + rand7()
for index > 40 {
index := (rand7()-1)*7 + rand7()
}
return index%10 + 1
}
// 执行用时 :16 ms, 在所有 Go 提交中击败了36.23%的用户
// 内存消耗 :4.8 MB, 在所有 Go 提交中击败了100.100%的用户
// 优化
func rand10() int {
for {
// 两个rand7() 生成 1~49
index := rand7() + (rand7()-1)*7
if index <= 40 {
return index%10 + 1
}
// 利用多出来的 1~9,生成 1~63
index = rand7() + (index-40-1)*7
if index <= 60 {
return index%10 + 1
}
// 利用多出来的 1~3,生成 1~21
index = rand7() + (index-60-1)*7
if index < 20 {
return index%10 + 1
}
}
}
// 执行用时 :12 ms, 在所有 Go 提交中击败了91.30%的用户
// 内存消耗 :4.8 MB, 在所有 Go 提交中击败了100.100%的用户