Implement Rand10() Using Rand7() - Complete Solution Guide
Implement Rand10() Using Rand7() is LeetCode problem 470, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given the API rand7() that generates a uniform random integer in the range [1, 7] , write a function rand10() that generates a uniform random integer in the range [1, 10] . You can only call the API rand7() , and you shouldn't call any other API. Please do not use a language's built-in random API. Each test case will have one internal argument n , the number of times that your implemented function rand10() will be called while testing. Note that this is not an argument passed to rand10() . Examp
Detailed Explanation
The problem requires implementing a `rand10()` function that generates uniformly random integers in the range [1, 10] using only the provided `rand7()` API, which generates uniformly random integers in the range [1, 7]. We are restricted to using only the `rand7()` function and must avoid using any built-in random number generation functions of the programming language. The key challenge is to convert the randomness from a base-7 system to a base-10 system while maintaining uniformity.
Solution Approach
The solution uses rejection sampling. It first calls `rand7()` twice to create a larger sample space (1-49). These calls can be thought of as generating digits in base-7. Then, it maps this sample space to a range that is a multiple of 10 (1-40). Numbers outside that range (41-49) are rejected. Because each value from 1-49 is equally likely, and only a multiple of 10 is used, we ensure that the mapping of values to numbers in range [1, 10] is also uniform. Finally, the values 1-40 are mapped to 1-10 using the modulo operator.
Step-by-Step Algorithm
- Step 1: Call `rand7()` twice and store the results in `row` and `col`.
- Step 2: Calculate an index value `idx` by combining `row` and `col`: `idx = (row - 1) * 7 + col`. This transforms the two calls into a single number ranging from 1 to 49. The formula is derived from treating the result as a base-7 number where the `row` is the 'tens' digit and `col` is the 'ones' digit.
- Step 3: Check if `idx` is within the acceptance range (1 to 40). If `idx > 40`, reject the sample and repeat from Step 1.
- Step 4: If `idx <= 40`, map `idx` to the range [1, 10] using the modulo operator: `return 1 + (idx - 1) % 10`.
Key Insights
- Insight 1: Combining the results of multiple calls to `rand7()` can create a larger, more controllable sample space.
- Insight 2: Rejection sampling is essential to ensure that the final output is uniformly distributed between 1 and 10.
- Insight 3: We need to create a sample space whose size is a multiple of 10 to enable uniform mapping to the [1, 10] range using the modulo operator.
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(1)
Topics
This problem involves: Math, Rejection Sampling, Randomized, Probability and Statistics.
Companies
Asked at: Tencent.