文章目錄
384. Shuffle an Array
https://leetcode.com/problems/shuffle-an-array/
Shuffle a set of numbers without duplicates.
Approach 1 : Mark Element
class Solution {
vector<int> nums;
public:
Solution(vector<int>& nums) {
this->nums = nums;
}
/** Resets the array to its original configuration and return it. */
vector<int> reset() {
return nums;
}
/** Returns a random shuffling of the array. */
vector<int> shuffle() {
vector<int> ans(nums.size());
vector<bool> mark(nums.size(), 0);
int findIndex;
for(int i=ans.size()-1; i>=0; i--) {
int random = rand()%(i + 1) + 1;
int n = 0;
for(int j = 0; j<mark.size(); j++) {
if(mark[j] == 0) {
n++;
if(n == random) {
mark[j] = 1;
ans[i] = nums[j];
break;
}
}
}
}
return ans;
}
};
/**
* 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();
*/
Runtime: 208 ms, faster than 58.55% of C++ online submissions for Shuffle an Array.
Memory Usage: 31.3 MB, less than 21.43% of C++ online submissions for Shuffle an Array.
Complexity Analysis
-
Time complexity :
Since we go through the array nums of length n. And for each character, we go through the array mark of length n. So the quadratic time complexity arises.
-
Space complexity :
Because we need to use linear additional space to store the original array for reset operation.
Also we need to mark the elements that are used. so we another linear additional space to store the mark flag for each element.
So the total space is
Approach 2 : Fish_Yates
Walk through all positions.
For each current position, select an random position and swap the value of the two position.
Proof:
-
For the first position, the probability is obviously for each value .*
So the probability of left values is .
-
For the second position, select an random value from . the probability is obviously for each value .
Because of
For the second position, the probability is for each value of
So the probability of left values is .
-
For the third position, select an random value from . the probability is obviously for each value .
because of
For the third position, the probability is for each value .
-
Similarly, we can prove that:
For ANY position, the probability is for each value .
class Solution {
private int[] array;
private int[] original;
Random rand = new Random();
private int randRange(int min, int max) {
return rand.nextInt(max - min) + min;
}
private void swapAt(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public Solution(int[] nums) {
array = nums;
original = nums.clone();
}
public int[] reset() {
array = original;
original = original.clone();
return original;
}
public int[] shuffle() {
for (int i = 0; i < array.length; i++) {
swapAt(i, randRange(i, array.length));
}
return array;
}
}
Runtime: 77 ms, faster than 70.11% of Java online submissions for Shuffle an Array.
Memory Usage: 50.8 MB, less than 100.00% of Java online submissions for Shuffle an Array.
class Solution {
vector<int> nums;
public:
Solution(vector<int> nums) {
this->nums = nums;
}
/** Resets the array to its original configuration and return it. */
vector<int> reset() {
return nums;
}
/** Returns a random shuffling of the array. */
vector<int> shuffle() {
vector<int> result(nums);
for (int i = 0;i < result.size();i++) {
int pos = rand()%(result.size()-i);
swap(result[i+pos], result[i]);
}
return result;
}
};
Runtime: 204 ms, faster than 75.73% of C++ online submissions for Shuffle an Array.
Memory Usage: 30.2 MB, less than 71.43% of C++ online submissions for Shuffle an Array.
Complexity Analysis
-
Time complexity :
Go through all element of arrays and generate a random index before the current element and swapping the current element and the random element
-
Space complexity :
Because we need to use linear additional space to store the original array for reset operation
Summary
1. Random Value
-
java
private int randRange(int min, int max) { // [min, max) left-opened right-closed return rand.nextInt(max - min) + min; }
-
cpp
for (int i = 0;i < result.size();i++) { int pos = rand()%(result.size()-i); swap(result[i+pos], result[i]); }