[LeetCode 470.] 用 Rand7() 实现 Rand10()

LeetCode 470. 用 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() ?

解题思路

这道题的关键思路是拒绝采样。对于范围在 [0,7) 的整型随机数,我们可以用i、j两个数组合成一个 7进制数 ij,也就是 10进制里的 i*7+j,这个数将随机均匀分布在 [0,49) 的范围内。
此时我们可以从中选出一定量的数字,使得这写数字可以恰好平均分成10份,把这10份分别映射到数字 0~9 即可。对于多出来的数字,直接拒绝,重新随机生成。
最典型的,选取 [0,40) 按照模10的余数进行分组,对于40及以上的数字,拒绝并重新生成。

参考代码

/*
 * @lc app=leetcode.cn id=470 lang=cpp
 *
 * [470] 用 Rand7() 实现 Rand10()
 */

// @lc code=start
// 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() {
        for (;;) {
            int i = rand7() - 1;
            int j = rand7() - 1;
            int res = i * 7 + j;
            if (res >= 40) continue;
            return res % 10 + 1;
        }
        return -1;
    } // AC
};
// @lc code=end
上一篇:剑指offer---lc 03---数组中重复元素--原地交换法


下一篇:leetcode题库学习系列——LC岛屿数量