【LeetCode】隨機化算法 random(共6題)

【384】Shuffle an Array(2019年3月12日)html

Shuffle a set of numbers without duplicates.程序員

實現一個類,裏面有兩個 api,structure 以下:面試

 

 1 class Solution {
 2 public:
 3     Solution(vector<int> nums) {
 4     }
 5     
 6     /** Resets the array to its original configuration and return it. */
 7     vector<int> reset() {
 8     }
 9     
10     /** Returns a random shuffling of the array. */
11     vector<int> shuffle() {
12     }
13 };

 

題解:咱們 shuffle 的時候,對於每個元素 res[i], 都隨機出一個 res[j],交換這兩個元素就能夠了。算法

 1 class Solution {
 2 public:
 3     Solution(vector<int> nums) {
 4         this->nums = nums;
 5     }
 6     
 7     /** Resets the array to its original configuration and return it. */
 8     vector<int> reset() {
 9         return nums;
10     }
11     
12     /** Returns a random shuffling of the array. */
13     vector<int> shuffle() {
14         const int n = nums.size();
15         vector<int> res(nums);
16         for (int i = 0; i < n; ++i) {
17             int j = rand() % n;
18             swap(res[i], res[j]);
19         }
20         return res;
21     }
22     vector<int> nums;
23 };
24 
25 /**
26  * Your Solution object will be instantiated and called as such:
27  * Solution obj = new Solution(nums);
28  * vector<int> param_1 = obj.reset();
29  * vector<int> param_2 = obj.shuffle();
30  */
View Code

 

 

【470】Implement Rand10() Using Rand7() (2018年11月15日,新學的算法)(2019年1月23日,算法羣複習)api

給了一個現成的api rand7(),這個接口能產生 [1,7] 區間的隨機數。根據這個api,寫一個 rand10() 的算法生成 [1, 10] 區間隨機數。 數組

題解:這個題《程序員代碼面試指南》上講了這題。我粗淺的描述一下產生過程:app

(1)rand7() 等機率的產生 1,2, 3, 4, 5, 6,7.dom

(2)rand7()-1 等機率的產生 [0, 6]ide

(3)(rand7() - 1) * 7 等機率的產生 0, 7, 14, 21, 28, 35, 42this

(4)(rand7() - 1) * 7 + (rand7() - 1)等機率的產生 [0, 48] 這49個數字

(5)若是步驟4的結果大於等於40,那麼就重複步驟4,直到產生的數小於40.

(6)把步驟5的結果mod 10再加1,就會等機率的隨機生成[1, 10].

總之,公式是 (randX() - 1) * X + (randX() - 1)。

 1 // The rand7() API is already defined for you.
 2 // int rand7();
 3 // @return a random integer in the range 1 to 7
 4 
 5 class Solution {
 6 public:
 7     int rand10() {
 8         int num = 0;
 9         do {
10             num = (rand7()-1) * 7 + (rand7()-1);
11         } while(num >= 40);
12         return num % 10 + 1;
13     }
14 };
View Code

本題還有兩個follow-up:

  1. What is the expected value for the number of calls to rand7() function?

  2. Could you minimize the number of calls to rand7()?

 《程序員代碼面試指南》後面的進階算法還沒看,chp 9, P391

 

【478】Generate Random Point in a Circle 

 

【497】Random Point in Non-overlapping Rectangles 

 

【519】Random Flip Matrix 

 

【528】Random Pick with Weight (2018年12月31日,昨天算法羣 mock 原題)

mock相關連接:http://www.javashuo.com/article/p-erhpzvlk-mt.html  (第一場-第四題)

Given an array w of positive integers, where w[i] describes the weight of index i, write a function pickIndex which randomly picks an index in proportion to its weight.

Note:

  1. 1 <= w.length <= 10000
  2. 1 <= w[i] <= 10^5
  3. pickIndex will be called at most 10000 times.
Example 1:
Input: 
["Solution","pickIndex"]
[[[1]],[]]
Output: [null,0]

Example 2:
Input: 
["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
[[[1,3]],[],[],[],[],[]]
Output: [null,0,1,1,1,0]

題解:把 weight 數組求前綴和,而後隨機出一個在區間 [0, tot) 中的隨機數,而後在前綴和數組中二分判斷index。

 1 class Solution {
 2 public:
 3     Solution(vector<int> w) {
 4         const int n = w.size();
 5         vector<int> summ2(n+1, 0);
 6         for (int i = 1; i <= n; ++i) {
 7             summ2[i] = w[i-1] + summ2[i-1];
 8         }
 9         summ = summ2;
10     }
11     
12     int pickIndex() {
13         int tot = summ.back();
14         int r = (rand() % tot) + 1;
15         auto iter = lower_bound(summ.begin(), summ.end(), r);
16         int ret = distance(summ.begin(), iter) - 1;
17         return ret;
18     }
19     vector<int> summ;
20 };
21 
22 /**
23  * Your Solution object will be instantiated and called as such:
24  * Solution obj = new Solution(w);
25  * int param_1 = obj.pickIndex();
26  */
View Code

 

【710】Random Pick with Blacklist

相關文章
相關標籤/搜索