ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

双散列表实现随机概率返回

2021-02-07 12:32:32  阅读:176  来源: 互联网

标签:双散 value 列表 map2 String map1 随机 key size


题目要求

设计一个结构,实现三个功能:
1.add();
将某个String添加到该结构中,做到不重复添加。
2.getRandom();
严格等概率随机返回结构中的任何一个key。
3.delete();
要求以上三个方法的时间复杂度全部为O(1)。

思路分析

1.add()
添加String,并且要求不重复。不重复?O(1)?想到什么?散列表。
2.getRandom()
严格等概率随机返回,相当于要求随机返回散列表中的一个key。首先要知道,散列函数的散列区间并不是严格等概率分布的,要想做到严格等概率分布,怎么实现?
严格等概率分布,相当于要求统计出到底有多少个key,然后用Math.random函数就能实现严格随机。如果统计有多少个key?如果遍历key。时间复杂度就不是1了。怎么实现1?可以用map实现,value依次加1,value对应的就是统计多少个key。但是,等我们通过Math.random函数求出随机的value时,如何找到对应的key?此时,可以考虑用双散列表实现。两个散列表的key和value依次对调
map1保存key-value(String,int)
map2保存value-key(int,String)
用map1保证key不会重复,然后用map2实现等概率随机。
3.delete()
删除方法,给定一个String,删除掉。
不过,有一个问题,等我们删除掉一个时,map中间就会出现一个空洞,此时再调用第二部的随机方法,就会出现问题。
因此,删除方法要能填补中间的空洞。可以先把最后一个复制到空洞处,然后删除最后一个。
map1中,把最后一个的value改成要删除的那个,此时最后一个和要删除的value相同,然后删除。
map2中,把要删除的num的value替换掉,然后删除最后一个。
最后。size–。

代码

import java.util.HashMap;

public class RandomPool {

    private HashMap<String,Integer> map1;
    private HashMap<Integer,String> map2;
    private int size;

    public RandomPool(){
        map1=new HashMap<>();
        map2=new HashMap<>();
        size=0;
    }

    public void add(String str){
        map1.put(str,size);
        map2.put(size,str);
        size++;
    }

    public String getRandom(){
        if(size==0){
            return null;
        }
        return map2.get((int)(Math.random()*size));
    }

    public void delete(String string){
        //获取要删除的num
        int num=map1.get(string);
        //获取最后一个
        String last = map2.get(size);
        //把最后一个复制到num的位置,此时有两个num
        map1.put(last,num);
        //删除string
        map1.remove(string);
        //替换到num位置的string,此时有两个last
        map2.put(num,last);
        //删除掉最后一个
        map2.remove(size);
        size--;
    }
}

标签:双散,value,列表,map2,String,map1,随机,key,size
来源: https://blog.csdn.net/weixin_43923436/article/details/113738721

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有