常数时间插入、删除和获取随机元素

flag

软件学院大三党,每天一道算法题,第八天

题目介绍

设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。

insert(val):当元素 val 不存在时,向集合中插入该项。
remove(val):元素 val 存在时,从集合中移除该项。
getRandom():随机返回现有集合中的一项。每个元素应该有相同的概率被返回。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/insert-delete-getrandom-o1

思路

核心思路是用hashmap记录数组每个值对应的下标,在插入和删除时不需要遍历数组寻找对应的数字下标,从而实现插入O(1)。

由于删除数组中的数据不是O(1),这里将数组中待删除的数字用数组最后一个数字代替,然后size - 1,下次insert的时候将size位置的数字覆盖,从而实现O(1)删除。不影响再次删除和产生随机数。

关键代码

public class RandomizedSet {
    /** Initialize your data structure here. */
    Map<Integer,Integer>map;//键为value,值为index
    ArrayList<Integer>list;
    int size;

    public RandomizedSet() {

        map=new HashMap<>();
        list=new ArrayList<>();
        size=0;
    }

    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {

        if(map.containsKey(val))
            return false;
        else {
            list.add(size,val);
            map.put(val,size);
            size++;
        }
        return true;

    }

    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        if(!map.containsKey(val))
            return false;
        else {
            int endValue=list.get(size-1);//list中最后一个元素
            int index=map.get(val);//val对应的索引值
            list.set(index,endValue);//将此索引值对应的元素换成endvalue
            map.put(endValue,index);
            map.remove(val);
            size--;
        }
        return true;

    }

    /** Get a random element from the set. */
    public int getRandom() {
        Random random=new Random();
        return list.get(random.nextInt(size));//产生的随机数为0-size的整数,不包括size

    }
}


测试

测试用例:

        RandomizedSet randomizedSet=new RandomizedSet();
        System.out.println(randomizedSet.insert(3));
        System.out.println(randomizedSet.remove(4));
        System.out.println(randomizedSet.insert(4));
        System.out.println(randomizedSet.insert(3));
        System.out.println(randomizedSet.insert(5));
        System.out.println(randomizedSet.remove(5));
        System.out.println(randomizedSet.getRandom());

结果:
结果

参考资料

Java中random的用法:
https://www.cnblogs.com/ningvsban/p/3590722.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值