返回介绍

solution / 0700-0799 / 0710.Random Pick with Blacklist / README

发布于 2024-06-17 01:03:35 字数 4676 浏览 0 评论 0 收藏 0

710. 黑名单中的随机数

English Version

题目描述

给定一个整数 n 和一个 无重复 黑名单整数数组 blacklist 。设计一种算法,从 [0, n - 1] 范围内的任意整数中选取一个 未加入 黑名单 blacklist 的整数。任何在上述范围内且不在黑名单 blacklist 中的整数都应该有 同等的可能性 被返回。

优化你的算法,使它最小化调用语言 内置 随机函数的次数。

实现 Solution 类:

  • Solution(int n, int[] blacklist) 初始化整数 n 和被加入黑名单 blacklist 的整数
  • int pick() 返回一个范围为 [0, n - 1] 且不在黑名单 blacklist 中的随机整数

 

示例 1:

输入
["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"]
[[7, [2, 3, 5]], [], [], [], [], [], [], []]
输出
[null, 0, 4, 1, 6, 1, 0, 4]

解释
Solution solution = new Solution(7, [2, 3, 5]);
solution.pick(); // 返回0,任何[0,1,4,6]的整数都可以。注意,对于每一个pick的调用,
         // 0、1、4和6的返回概率必须相等(即概率为1/4)。
solution.pick(); // 返回 4
solution.pick(); // 返回 1
solution.pick(); // 返回 6
solution.pick(); // 返回 1
solution.pick(); // 返回 0
solution.pick(); // 返回 4

 

提示:

  • 1 <= n <= 109
  • 0 <= blacklist.length <= min(105, n - 1)
  • 0 <= blacklist[i] < n
  • blacklist 中所有值都 不同
  •  pick 最多被调用 2 * 104 次

解法

方法一:哈希表

class Solution:
  def __init__(self, n: int, blacklist: List[int]):
    self.k = n - len(blacklist)
    self.d = {}
    i = self.k
    black = set(blacklist)
    for b in blacklist:
      if b < self.k:
        while i in black:
          i += 1
        self.d[b] = i
        i += 1

  def pick(self) -> int:
    x = randrange(self.k)
    return self.d.get(x, x)


# Your Solution object will be instantiated and called as such:
# obj = Solution(n, blacklist)
# param_1 = obj.pick()
class Solution {
  private Map<Integer, Integer> d = new HashMap<>();
  private Random rand = new Random();
  private int k;

  public Solution(int n, int[] blacklist) {
    k = n - blacklist.length;
    int i = k;
    Set<Integer> black = new HashSet<>();
    for (int b : blacklist) {
      black.add(b);
    }
    for (int b : blacklist) {
      if (b < k) {
        while (black.contains(i)) {
          ++i;
        }
        d.put(b, i++);
      }
    }
  }

  public int pick() {
    int x = rand.nextInt(k);
    return d.getOrDefault(x, x);
  }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(n, blacklist);
 * int param_1 = obj.pick();
 */
class Solution {
public:
  unordered_map<int, int> d;
  int k;

  Solution(int n, vector<int>& blacklist) {
    k = n - blacklist.size();
    int i = k;
    unordered_set<int> black(blacklist.begin(), blacklist.end());
    for (int& b : blacklist) {
      if (b < k) {
        while (black.count(i)) ++i;
        d[b] = i++;
      }
    }
  }

  int pick() {
    int x = rand() % k;
    return d.count(x) ? d[x] : x;
  }
};

/**
 * Your Solution object will be instantiated and called as such:
 * Solution* obj = new Solution(n, blacklist);
 * int param_1 = obj->pick();
 */
type Solution struct {
  d map[int]int
  k int
}

func Constructor(n int, blacklist []int) Solution {
  k := n - len(blacklist)
  i := k
  black := map[int]bool{}
  for _, b := range blacklist {
    black[b] = true
  }
  d := map[int]int{}
  for _, b := range blacklist {
    if b < k {
      for black[i] {
        i++
      }
      d[b] = i
      i++
    }
  }
  return Solution{d, k}
}

func (this *Solution) Pick() int {
  x := rand.Intn(this.k)
  if v, ok := this.d[x]; ok {
    return v
  }
  return x
}

/**
 * Your Solution object will be instantiated and called as such:
 * obj := Constructor(n, blacklist);
 * param_1 := obj.Pick();
 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文