1. 描述

  • 给定一个包含 [0,n) 中不重复整数的黑名单 blacklist ,写一个函数从 [0, n) 中返回一个不在 blacklist 中的随机整数。
    对它进行优化使其尽量少的调用Math.random()

  • You are given an integer n and an array of unique integers blacklist. Design an algorithm to pick a random integer in the range [0, n - 1] that is not in blacklist. Any integer that is in the mentioned range and not in blacklist should be equally likely returned.
    Optimize your algorithm such that it minimizes the call to the built-in random function of your language.
    Implement the Solution class:

    • Solution(int n, int[] blacklist) Initializes the object with the integer n and the blacklisted integers blacklist.
    • int pick() Returns a random integer in the range [0, n - 1] and not in blacklist. All the possible integers should be equally likely returned.

2. 分析

  • 第一想法:每次生成随机数都判断是否在黑名单内,在则重新生成,但这样的设计不符合尽量少调用random()的要求。
  • 大致思路:那么如何做到尽量少的调用random()呢?如果生成的随机数一定不在黑名单中,则每次pick()只用调用一次random(),这就需要我们把[0, n)看成一个数组,把黑名单中的数移到末尾,由于知道黑名单中有多少个数,我们就可以知道应该生成零到几的随机数了。
  • 具体思路:将黑名单中的数移到末尾如何实现呢?其实数组[0, n)相当于最终被分成了定长的两块,前一部分为白名单,后一部分为黑名单。正常来说想法是遍历原数组,如果在黑名单中,则把数交换到末尾。但这样做有两个问题:一是如何快速判断当前数在不在黑名单中,二是需要确定交换的数不在黑名单中。
  • 问题一的本质是如何快速查询一个数在不在一个集合中,可以通过把黑名单中的数存进哈希表来来解决。第二个问题在创建哈希表后也得到解决。同时在建立了哈希表后,就不再需要遍历数组了,只需要在哈希表中进行查找,如果哈希表中的数在数组的黑名单区间,则不用移动。
  • 整体算法为:
    • 把0~N分成两段,前半段为白名单,后半段为黑名单:先建立一个存有所有黑名单数的map便于查询,再将在前半段范围内的黑名单数与在后半段的白名单数建立映射(作为键值对加入map),这样相当于前半段都是白名单数
    • 取随机数:只用在前半段内取随机数,若取到了黑名单数,则去map中取对应的白名单数作为返回值即可

3. 代码

class Solution {Random random;Map<Integer, Integer> blackmap;int thre;public Solution(int n, int[] blacklist) {random = new Random();blackmap = new HashMap<>();// 将blacklist中的数存入hashmap,便于查询一个数是否在blacklist中for(int b: blacklist){blackmap.put(b, 66);}thre = n - blacklist.length;int last = n - 1;for(int b: blacklist){if(b >= thre) continue;while(blackmap.containsKey(last)){last--;}// 在hashmap中存入替换的值blackmap.put(b, last);// 存值后last要记得--,不然下一个黑名单中的数依然会用这个值替换last--;}}public int pick() {int rand = random.nextInt(thre);if(blackmap.containsKey(rand)){return blackmap.get(rand);} else {return rand;}}
}

710. Random Pick with Blacklist 黑名单中的随机数(Hard)相关推荐

  1. 710. Random Pick with Blacklist - LeetCode

    为什么80%的码农都做不了架构师?>>>    Question 710. Random Pick with Blacklist Solution 题目大意:给一个N,表示一个范围[ ...

  2. Java实现 LeetCode 710 黑名单中的随机数(黑白名单)

    710. 黑名单中的随机数 给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数. 对它进行优化使其尽量少调用系统方法 Math.ran ...

  3. 2022/6/26每日一题———黑名单中的随机数

    题目: 黑名单中的随机数 个人思路: 直接得到0~n范围一个随机数,然后判断是不是在黑名单里面,不在的话就输出,在的话就重复执行pick()函数.缺点很明显,如果得到了一个随机数在黑名单中,那我们就需 ...

  4. 710. 黑名单中的随机数

    给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数. 对它进行优化使其尽量少调用系统方法 Math.random() . 提示: 1 ...

  5. LeetCode 黑名单中随机数(图解)

    给定一个包含 [0,n ) 中独特的整数的黑名单 B,写一个函数从 [ 0,n ) 中返回一个不在 B 中的随机整数. 对它进行优化使其尽量少调用系统方法 Math.random() . 提示: 1 ...

  6. MTK方案上基于Android N拦截黑名单中的短/彩信的方法

    --- 作者 zuhui.zhang 安卓7.0原生系统增加了在framework层拦截黑名单来电和短信,但不会将数据保存到数据库,因此无法查看到被拦截的来电和短信.在安卓7.0之前,黑名单的短信默认 ...

  7. 398. Random Pick Index - LeetCode

    为什么80%的码农都做不了架构师?>>>    Question 398. Random Pick Index Solution 思路:重点是如果数据中有多个数target相等,要从 ...

  8. 案件被终本后,失信被执行人会从黑名单中移除吗?

    转自:http://wenzhang.ztcztc.com/Detail.aspx?id=2EAA50DD-D49D-DA2D-5347-75FCED76FD65 由于债权债务关系的复杂性,近年来想要 ...

  9. fail2ban从黑名单中移除IP

    fail2ban从黑名单中移除IP tags: 网站 个人网站:wanghualong.cn fail2ban从黑名单(ban list)中移除IP的方法: 网上一堆教程长篇大论,废话连篇其实只需要一 ...

最新文章

  1. 核心动画的接触点滴(五)
  2. 挂起和阻塞区别以及sleep和wait的区别
  3. 360下载的mysql_MySQL数据库5.7
  4. Ajax中什么时候用同步,什么时候用异步?
  5. 一篇文章,了解清楚路由器的各种组网
  6. 如何实现多路海康大华等RTSP数据转RTMP推送
  7. Ubuntu 配置vsftpd实现FTP服务器
  8. mybatis直接执行sql_拼多多二面:Mybatis是如何执行一条SQL命令的?
  9. 基于点云的视觉引导系统
  10. SSH框架调用scrapy爬虫
  11. python 共享内存 c_如何在python和C/C++中使用共享内存
  12. 如何屏蔽 iOS 软件自动更新,去除更新通知和标记
  13. 浅谈对于机器学习的理解
  14. Input输入框的失焦
  15. 重庆文理学院计算机公众号,重庆文理学院各微信公众号影响力排行榜新鲜出炉啦!!!...
  16. FFMpeg.AutoGen(1)讲解官方example代码:Main函数、 解码
  17. 钉钉分享唤起三方app
  18. 移动互联网App推广的十大难题
  19. 后缀是php,php是什么文件_文件后缀php是什么意思
  20. 三维重建 影像匹配 密集匹配三者的关系

热门文章

  1. 助创cms二手车众筹系统:汽车众筹平台绝佳时机来临!
  2. moment.js时间操作后24小时制变成了12小时制
  3. 微信小程序video组件调用腾讯视频的解决方案
  4. php在foreach循环后留下数组的引用问题
  5. SaltStack常用模块之file
  6. K-means聚类详解
  7. ubuntu如何连接显示器
  8. 巴别塔合约作战终端开发日记3——服务器负载优化
  9. 基于Pushlet实现的网站消息推送
  10. C++应用之HAL层文件逻辑