题目描述:
题中给出一个 n_rows 行 n_cols 列的二维矩阵,且所有值被初始化为 0。要求编写一个 flip 函数,均匀随机的将矩阵中的 0 变为 1,并返回该值的位置下标 [row_id,col_id];同样编写一个 reset 函数,将所有的值都重新置为 0。尽量最少调用随机函数 Math.random(),并且优化时间和空间复杂度。
注意:
1 <= n_rows, n_cols <= 10000
0 <= row.id < n_rows 并且 0 <= col.id < n_cols
当矩阵中没有值为 0 时,不可以调用 flip 函数
调用 flip 和 reset 函数的次数加起来不会超过 1000 次
示例 1:
输入:
[“Solution”,“flip”,“flip”,“flip”,“flip”]
[[2,3],[],[],[],[]]
输出: [null,[0,1],[1,2],[1,0],[1,1]]
示例 2:
输入:
[“Solution”,“flip”,“flip”,“reset”,“flip”]
[[1,2],[],[],[],[]]
输出: [null,[0,0],[0,1],null,[0,0]]
输入语法解释:
输入包含两个列表:被调用的子程序和他们的参数。Solution 的构造函数有两个参数,分别为 n_rows 和 n_cols。flip 和 reset 没有参数,参数总会以列表形式给出,哪怕该列表为空
方法1:
主要思路:解题汇总链接
(1)先将给定的二维数组转化为对应的一维数组进行存储,每次对一维数组的长度取模,找到一个没有使用过的位置,返回对应位置的二维表示;
class Solution {
public:
int row;
int col;
int len;
vector<bool> mp;
Solution(int n_rows, int n_cols):row(n_rows),col(n_cols) {
len=n_cols*n_rows;
mp=vector<bool>(len,false);//转化为对应的一维形式
}
vector<int> flip() {
int rand_n=rand()%(len);
while(mp[rand_n]){//直到找到没有使用过的位置
rand_n=rand()%(len);
}
mp[rand_n]=true;//标识使用过
return {rand_n/col,rand_n%col};
}
void reset() {
mp=vector<bool>(len,false);//重置
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(n_rows, n_cols);
* vector<int> param_1 = obj->flip();
* obj->reset();
*/
方法2:
主要思路:
(1)同样是想对一维的数组进行取模,找出对应的位置进行返回,但是将原来的一维数组分成了已经使用过和没有使用过的两部分,将使用过的位置进行映射,映射到没有使用过的位置,这样,可以每次对当前的长度进行取模,然后一次找到没有使用过的位置,进行返回,并重新处理映射关系;
class Solution {
public:
int row;
int col;
int len;
unordered_map<int,int> mp;//存储映射关系
Solution(int n_rows, int n_cols):row(n_rows),col(n_cols) {
len=n_cols*n_rows;
}
vector<int> flip() {
int index=rand()%len;//获得当前随机数
int res;//实际的最后要返回的位置
if(mp.count(index)){
res=mp[index];//若有映射值,则为映射值
}
else{
res=index;//否则,即为实际的值
}
//将当前使用过的随机值映射为新的没有使用过的值
//由于长度要减1,为了处理索引 len-1 出的映射值,将其放入到当前随机值的映射值处
if(mp.count(len-1)){
mp[index]=mp[len-1];
mp.erase(len-1);
}
else{
mp[index]=len-1;
}
--len;//长度减1
return {res/col,res%col};
}
void reset() {
//重置长度和映射
len=row*col;
mp.clear();
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(n_rows, n_cols);
* vector<int> param_1 = obj->flip();
* obj->reset();
*/