给定方法 rand7
可生成 [1,7]
范围内的均匀随机整数,试写一个方法 rand10
生成 [1,10]
范围内的均匀随机整数。
你只能调用 rand7()
且不能调用其他方法。请不要使用系统的 Math.random()
方法。
每个测试用例将有一个内部参数 n
,即你实现的函数 rand10()
在测试时将被调用的次数。请注意,这不是传递给 rand10()
的参数。
// 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() {
int row, col, idx;
do{
row = rand7();
col = rand7();
idx = col + (row - 1) * 7;
}while(idx > 40);
return 1+(idx-1) % 10;
}
};
给定圆的半径和圆心的位置,实现函数 randPoint
,在圆中产生均匀随机点。
实现 Solution
类:
Solution(double radius, double x_center, double y_center)
用圆的半径radius
和圆心的位置(x_center, y_center)
初始化对象randPoint()
返回圆内的一个随机点。圆周上的一点被认为在圆内。答案作为数组返回[x, y]
。
class Solution {
private:
mt19937 gen{random_device{}()};
uniform_real_distribution<double> dis;
double xc, yc, r;
public:
Solution(double radius, double x_center, double y_center): dis(-radius, radius), xc(x_center), yc(y_center), r(radius) {}
vector<double> randPoint() {
while (true) {
double x = dis(gen), y = dis(gen);
if (x * x + y * y <= r * r) {
return {xc + x, yc + y};
}
}
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(radius, x_center, y_center);
* vector<double> param_1 = obj->randPoint();
*/
给你一个可能含有 重复元素 的整数数组 nums
,请你随机输出给定的目标数字 target
的索引。你可以假设给定的数字一定存在于数组中。
实现 Solution
类:
Solution(int[] nums)
用数组nums
初始化对象。int pick(int target)
从nums
中选出一个满足nums[i] == target
的随机索引i
。如果存在多个有效的索引,则每个索引的返回概率应当相等。
class Solution {
unordered_map<int, vector<int>> mymap;
public:
Solution(vector<int>& nums) {
for(int i = 0; i<nums.size(); i++){
if(mymap.count(nums[i]) == 0){
mymap[nums[i]] = {};
mymap[nums[i]].push_back(i);
}else{
mymap[nums[i]].push_back(i);
}
}
}
int pick(int target) {
int index = rand() % mymap[target].size();
return mymap[target][index];
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(nums);
* int param_1 = obj->pick(target);
*/
给你一个整数数组 nums
,设计算法来打乱一个没有重复元素的数组。打乱后,数组的所有排列应该是 等可能 的。
实现 Solution
class:
Solution(int[] nums)
使用整数数组nums
初始化对象int[] reset()
重设数组到它的初始状态并返回int[] shuffle()
返回数组随机打乱后的结果
Fisher-Yates 洗牌算法
class Solution {
vector<int> &origin;
vector<int> curr;
public:
Solution(vector<int>& nums) : origin(nums) {
srand(time(nullptr));
curr.assign(nums.begin(), nums.end());
}
vector<int> reset() {
return origin;
}
vector<int> shuffle() {
for(int i = curr.size()-1; i >= 0; i--){
int j = rand() % (i+1);
swap(curr[i], curr[j]);
}
return curr;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(nums);
* vector<int> param_1 = obj->reset();
* vector<int> param_2 = obj->shuffle();
*/
给你一个 m x n
的二元矩阵 matrix
,且所有值被初始化为 0
。请你设计一个算法,随机选取一个满足 matrix[i][j] == 0
的下标 (i, j)
,并将它的值变为 1
。所有满足 matrix[i][j] == 0
的下标 (i, j)
被选取的概率应当均等。
尽量最少调用内置的随机函数,并且优化时间和空间复杂度。
实现 Solution
类:
Solution(int m, int n)
使用二元矩阵的大小m
和n
初始化该对象int[] flip()
返回一个满足matrix[i][j] == 0
的随机下标[i, j]
,并将其对应格子中的值变为1
void reset()
将矩阵中所有的值重置为0
class Solution {
vector<int> matrix;
int m, n;
int total;
public:
Solution(int _m, int _n): m(_m), n(_n){
matrix = vector<int>(m * n, 0);
for(int i = 0; i< m*n; i++){
matrix[i] = i;
}
srand(time(nullptr));
total = m * n;
}
vector<int> flip() {
int index = rand() % total;
swap(matrix[index], matrix[--total]);
return {matrix[total] / n, matrix[total] % n};
}
void reset() {
for(int i = total; i< m*n; i++){
int before = matrix[total];
swap(matrix[total], matrix[before]);
}
total = m * n;
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(m, n);
* vector<int> param_1 = obj->flip();
* obj->reset();
*/
给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。
实现 Solution
类:
Solution(ListNode head)
使用整数数组初始化对象。int getRandom()
从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相等。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
unordered_map<int, int> mymap;
int index;
public:
Solution(ListNode* head) {
ListNode *p = head;
index = 0;
while(p){
mymap[index++] = p->val;
p = p->next;
}
srand(time(nullptr));
}
int getRandom() {
return mymap[rand() % index];
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(head);
* int param_1 = obj->getRandom();
*/
给定一个由非重叠的轴对齐矩形的数组 rects
,其中 rects[i] = [ai, bi, xi, yi]
表示 (ai, bi)
是第 i
个矩形的左下角点,(xi, yi)
是第 i
个矩形的右上角点。设计一个算法来随机挑选一个被某一矩形覆盖的整数点。矩形周长上的点也算做是被矩形覆盖。所有满足要求的点必须等概率被返回。
在给定的矩形覆盖的空间内的任何整数点都有可能被返回。
请注意 ,整数点是具有整数坐标的点。
实现 Solution
类:
Solution(int[][] rects)
用给定的矩形数组rects
初始化对象。int[] pick()
返回一个随机的整数点[u, v]
在给定的矩形所覆盖的空间内。
class Solution {
vector<int> nums;
vector<pair<int,int>> coordinate;
vector<pair<int,int>> startCoord;
int total = 0;
public:
Solution(vector<vector<int>>& rects) {
for(auto &rect: rects){
startCoord.push_back({rect[0], rect[1]});
nums.push_back(getNums(rect));
total += nums.back();
}
srand(time(nullptr));
}
int getNums(vector<int> &rect){
int m = rect[2]-rect[0]+1;
int n = rect[3]-rect[1]+1;
coordinate.push_back({m, n});
return m * n;
}
vector<int> pick() {
int num = rand() % total;
int index = 0;
for(int i = 0; i<nums.size(); i++){
if(num < nums[i]){
index = i;
break;
}else{
num -= nums[i];
}
}
int m = coordinate[index].first, n = coordinate[index].second;
int x = num / n, y = num % n;
int start_x = startCoord[index].first, start_y = startCoord[index].second;
return {start_x + x, start_y + y};
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(rects);
* vector<int> param_1 = obj->pick();
*/