This algorithm can be used for leetcode 519. The algorithm is called Fisher-Yates shuffle.
The question is to output the index of an array in a random order (we don’t care the actual value stored at that position), and minimize the number of rand()
called and also optimize for space and time complexity.
e.g.: Given array of size 6, the output may look like the following:1
(0, 3), (0, 1), (0, 2), (0, 4), (0, 0), (0, 5)
To achieve this, we can use the following code:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36// Get a random number in range [minVal, maxVal].
int getRand(int minVal, int maxVal) {
return rand() % (maxVal - minVal + 1) + minVal;
}
vector<int> solution(const vector<int>& vec) {
int maxVal = vec.size() - 1;
unordered_map<int, int> hm;
vector<int> rtn;
// We loop vec.size() times to get output all the index.
for(int i = 0; i < vec.size(); i ++) {
// Choose a random index in range [0, maxVal].
int randIdx = getRand(0, maxVal);
int currSelectedIdx;
// If we have not seen randIdx before,
// it means that randIdx is the current selected index, and we can just return it.
if(hm.find(randIdx) == hm.end()) {
currSelectedIdx = randIdx;
} else {
// If we have seen randIdx before, it means that randIdx has been selected before.
// And, we need to select the index in hm[randIdx], which is what randIdx represents now.
currSelectedIdx = hm[randIdx];
}
// After the index for current iteration is determined, we need to swap it with the index represented by current maxVal.
// If maxVal still represents maxVal.
if(hm.find(maxVal) == hm.end()) {
hm[randIdx] = maxVal;
} else {
// IMPORTANT !!!
// If maxVal has been chosen before, and it now represents something else.
hm[randIdx] = hm[maxVal];
}
maxVal --;
rtn.push_back(currSelectedIdx);
}
}
This code can be easily extended to 2-D matrix, as we just have to convert maxVal
into rowCnt * colCnt - 1
. And randIdx
has to be converted to (row, col)
by using:1
2int row = randIdx / colCnt;
int col = randIdx % colCnt;
Here’s an example of running the algorithm:
1 | init: |