实现一个插入,删除,随机都是O(1)复杂度的Set

题目

实现一个Set,要求

add O(1)

remove O(1)

random O(1)

分析

同时使用两种数据结构

ArrayList: 保存所有元素

HashMap: key为元素,value为元素在ArrayList中的下标

add: 

    ArrayList.add O(1) 

    HashMap add O(1)

random: ArrayList里随机取一个值

remove: 

    HashMap中找到元素在ArrayList中的下标 O(1)

    删除HashMap中的元素 O(1)

    将ArrayList最后一个元素copy到删除元素所在位置 O(1)

    删除最后一个元素 O(1)

    更新被copy元素在HashMap中的value O(1)

代码

public class RandomSet<E> {
    List<E> dta = new ArrayList<E>();
    Map<E, Integer> idx = new HashMap<E, Integer>();
    public boolean add(E item) {
        if (idx.containsKey(item)) {
            return false;
        }
        idx.put(item, dta.size());
        dta.add(item);
        return true;
    }
    public E removeAt(int id) {
        if (id >= dta.size()) {
            return null;
        }
        E res = dta.get(id);
        idx.remove(res);
        E last = dta.remove(dta.size() - 1);
        // skip filling the hole if last is removed
        if (id < dta.size()) {
            idx.put(last, id);
            dta.set(id, last);
        }
        return res;
    }
    public boolean remove(E item) {
        Integer id = idx.get(item);
        if (id == null) {
            return false;
        }
        removeAt(id);
        return true;
    }
    public E random(Random rnd) {
        if (dta.isEmpty()) {
            return null;
        }
        int id = rnd.nextInt(dta.size());
        return removeAt(id);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值