日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/3/7 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 710. Random Pick with Blacklist 黑名单中的随机数(Hard) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 描述

  • 給定一個(gè)包含 [0,n) 中不重復(fù)整數(shù)的黑名單 blacklist ,寫一個(gè)函數(shù)從 [0, n) 中返回一個(gè)不在 blacklist 中的隨機(jī)整數(shù)。
    對它進(jìn)行優(yōu)化使其盡量少的調(diào)用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. 分析

  • 第一想法:每次生成隨機(jī)數(shù)都判斷是否在黑名單內(nèi),在則重新生成,但這樣的設(shè)計(jì)不符合盡量少調(diào)用random()的要求。
  • 大致思路:那么如何做到盡量少的調(diào)用random()呢?如果生成的隨機(jī)數(shù)一定不在黑名單中,則每次pick()只用調(diào)用一次random(),這就需要我們把[0, n)看成一個(gè)數(shù)組,把黑名單中的數(shù)移到末尾,由于知道黑名單中有多少個(gè)數(shù),我們就可以知道應(yīng)該生成零到幾的隨機(jī)數(shù)了。
  • 具體思路:將黑名單中的數(shù)移到末尾如何實(shí)現(xiàn)呢?其實(shí)數(shù)組[0, n)相當(dāng)于最終被分成了定長的兩塊,前一部分為白名單,后一部分為黑名單。正常來說想法是遍歷原數(shù)組,如果在黑名單中,則把數(shù)交換到末尾。但這樣做有兩個(gè)問題:一是如何快速判斷當(dāng)前數(shù)在不在黑名單中,二是需要確定交換的數(shù)不在黑名單中。
  • 問題一的本質(zhì)是如何快速查詢一個(gè)數(shù)在不在一個(gè)集合中,可以通過把黑名單中的數(shù)存進(jìn)哈希表來來解決。第二個(gè)問題在創(chuàng)建哈希表后也得到解決。同時(shí)在建立了哈希表后,就不再需要遍歷數(shù)組了,只需要在哈希表中進(jìn)行查找,如果哈希表中的數(shù)在數(shù)組的黑名單區(qū)間,則不用移動。
  • 整體算法為:
    • 把0~N分成兩段,前半段為白名單,后半段為黑名單:先建立一個(gè)存有所有黑名單數(shù)的map便于查詢,再將在前半段范圍內(nèi)的黑名單數(shù)與在后半段的白名單數(shù)建立映射(作為鍵值對加入map),這樣相當(dāng)于前半段都是白名單數(shù)
    • 取隨機(jī)數(shù):只用在前半段內(nèi)取隨機(jī)數(shù),若取到了黑名單數(shù),則去map中取對應(yīng)的白名單數(shù)作為返回值即可

3. 代碼

class Solution {Random random;Map<Integer, Integer> blackmap;int thre;public Solution(int n, int[] blacklist) {random = new Random();blackmap = new HashMap<>();// 將blacklist中的數(shù)存入hashmap,便于查詢一個(gè)數(shù)是否在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要記得--,不然下一個(gè)黑名單中的數(shù)依然會用這個(gè)值替換last--;}}public int pick() {int rand = random.nextInt(thre);if(blackmap.containsKey(rand)){return blackmap.get(rand);} else {return rand;}} }

總結(jié)

以上是生活随笔為你收集整理的710. Random Pick with Blacklist 黑名单中的随机数(Hard)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。