Random Pick with Blacklist in C++


Suppose we have a blacklist called B. This is holing unique integers from range [0, N), we have to define a function to return a uniform random integer from range [0, N) which is NOT in B. We will try to make this function more optimized by reducing random(). function call. Suppose the input array is like

To solve this, we will follow these steps −

Define one map

  • We will initialize with N and array v.
  • for initalize i := 0, when i < size of v, update (increase i by 1), do −
    • if v[i] < N, then:, m[v[i]] := -1
  • M := N – size of m
  • n := size of v
  • for initialize i := 0, when i < size of v, update (increase i by 1), do −
    • if v[i] < M, then −
      • decrease N by 1
      • while N is in m, do −
        • decrease N by 1
      • m[v[i]] := N
  • Define a function pick()
  • x := random number mod M
  • return (if x is present in m, then m[x], otherwise x)

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   int M;
   map <int,int> m;
   Solution(int N, vector<int>& v) {
      for(int i = 0; i < v.size(); i++){
         if(v[i] < N) m[v[i]] = -1;
      }
      M = N - (int)(m.size());
      int n = v.size();
      for(int i = 0; i < v.size(); i++){
         if(v[i] < M){
            while(m.count(--N));
            m[v[i]] = N;
         }
      }
   }
   int pick() {
      int x = rand() % M;
      return m.count(x)? m[x] : x;
   }
};
main(){
   vector<int> v = {2};
   Solution ob(4,v);
   cout << (ob.pick()) << endl;
   cout << (ob.pick()) << endl;
   cout << (ob.pick()) << endl;
}

Input

Give N = 4 and array [2]

Output

1
1
0

Updated on: 02-Jun-2020

140 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements