本文主要是介绍384. Shuffle an Array,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 384. Shuffle an Array
- Approach 1 : Mark Element
- Complexity Analysis
- Approach 2 : Fish_Yates
- Proof:
- Complexity Analysis
- Summary
- 1. Random Value
- 2. Re-emphasize: [left-opened right-closed)
- 3. Shuffle Method
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 : O ( n 2 ) O(n^2) O(n2)
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 : O ( n ) O(n) O(n)
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 n + n = 2 n = O ( n ) n + n = 2n = O(n) n+n=2n=O(n)
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 1 n \frac{1}{n} n1 obviously for each value [ 0 , n ) [0, n) [0,n).*
So the probability of left values [ 1 , n ) [1, n) [1,n) is n − 1 n \frac{n-1}{n} nn−1 .
-
For the second position, select an random value from [ 1 , n ) [1, n) [1,n). the probability is 1 n − 1 \frac{1}{n - 1} n−11 obviously for each value [ 1 , n ) [1, n) [1,n) .
Because of n − 1 n ∗ 1 n − 1 = 1 n \frac{n-1}{n}*\frac{1}{n-1} = \frac{1}{n} nn−1∗n−11=n1
For the second position, the probability is 1 n \frac{1}{n} n1 for each value of [ 0 , n ) [0, n) [0,n)
So the probability of left values [ 2 , n ) [2, n) [2,n) is n − 2 n \frac{n-2}{n} nn−2 .
-
For the third position, select an random value from [ 2 , n ) [2, n) [2,n). the probability is 1 n − 2 \frac{1}{n - 2} n−21 obviously for each value [ 2 , n ) [2, n) [2,n) .
because of n − 2 n ∗ 1 n − 2 = 1 n \frac{n-2}{n}*\frac{1}{n-2} = \frac{1}{n} nn−2∗n−21=n1
For the third position, the probability is 1 n \frac{1}{n} n1 for each value [ 0 , n ) [0, n) [0,n).
-
Similarly, we can prove that:
For ANY position, the probability is 1 n \frac{1}{n} n1 for each value [ 0 , n ) [0, n) [0,n).
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 : O ( n ) O(n) O(n)
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 : O ( n ) O(n) O(n)
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-closedreturn 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]);}
2. Re-emphasize: [left-opened right-closed)
3. Shuffle Method
这篇关于384. Shuffle an Array的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!