• 【LeetCode】随机化算法 random(共6题)


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

    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 rand7(),这个接口能产生 [1,7] 区间的随机数。根据这个api,写一个 rand10() 的算法生成 [1, 10] 区间随机数。 

    题解:这个题《程序员代码面试指南》上讲了这题。我粗浅的描述一下产生过程:

    (1)rand7() 等概率的产生 1,2, 3, 4, 5, 6,7.

    (2)rand7()-1 等概率的产生 [0, 6]

    (3)(rand7() - 1) * 7 等概率的产生 0, 7, 14, 21, 28, 35, 42

    (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相关链接:https://www.cnblogs.com/zhangwanying/p/10199941.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 

  • 相关阅读:
    poj 3590 The shuffle Problem——DP+置换
    poj 3128 Leonardo's Notebook——思路(置换)
    bzoj 1004 [HNOI2008]Cards && poj 2409 Let it Bead ——置换群
    bzoj 1119 [POI2009]SLO && bzoj 1697 [Usaco2007 Feb]Cow Sorting牛排序——思路(置换)
    bzoj 3944 Sum —— 杜教筛
    bzoj 1367 [ Baltic 2004 ] sequence —— 左偏树
    bzoj 2093 [ Poi 2010 ] Frog —— 滑动窗口 + 倍增
    bzoj 2276 [ Poi 2011 ] Temperature —— 单调队列
    bzoj 2069 [ POI 2004 ] ZAW —— 多起点最短路 + 二进制划分
    NOIP2007普及 守望者的逃离
  • 原文地址:https://www.cnblogs.com/zhangwanying/p/9964660.html
Copyright © 2020-2023  润新知