常数时间删除-查找数组中的任意元素

文章介绍了如何结合哈希表和数组来优化数据结构,以实现数组中元素的快速插入、删除和随机获取,时间复杂度均为O(1)。具体方法包括将待删除元素移动至数组尾部并弹出,以及在存在黑名单的情况下生成不包含黑名单的随机数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文档阅读

文档阅读

结合哈希表和数组,使得数组的删除操作时间复杂度变成 O(1)
对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)。
在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop 掉。
想高效地,等概率地随机获取元素,就要使用数组作为底层容器

题目

380. O(1) 时间插入、删除和获取随机元素

class RandomizedSet {
    List<Integer> list;
    Map<Integer, Integer> map;
    public RandomizedSet() {
        list = new ArrayList<>();
        map = new HashMap<>();
    }
    
    public boolean insert(int val) {
        if(map.containsKey(val)) return false;
        map.put(val, list.size());
        list.add(val);
        return true;
    }
    
    public boolean remove(int val) {
        if(!map.containsKey(val)) return false;
        Integer removeIdx = map.get(val);
        map.put(list.get(list.size() - 1), removeIdx);
        //数组交换位置
        Collections.swap(list, removeIdx, list.size() - 1);
        map.remove(val);
        list.remove(list.size() - 1);
        return true;
    }
    
    public int getRandom() {
        return list.get((int)(Math.random() * list.size()));
    }
}

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet obj = new RandomizedSet();
 * boolean param_1 = obj.insert(val);
 * boolean param_2 = obj.remove(val);
 * int param_3 = obj.getRandom();
 */

710. 黑名单中的随机数

class Solution {
    int size;
    Map<Integer, Integer> map;
    Random random;
    public Solution(int n, int[] blacklist) {
        size = n - blacklist.length;
        map = new HashMap<>();
        random = new Random();
        for(int b : blacklist){
            map.put(b, 0);//这里放什么值都无所谓只是让map记录这里是黑名单
        }
        int idx = n - 1;//将所有黑名单都映射到[size, n)之间
        for(int b : blacklist){
            if(b >= size) continue;//已经在的就不处理
            while(map.containsKey(idx)) idx--;
            map.put(b, idx);
            idx--;
        }
    }
    
    public int pick() {
        int num = random.nextInt(size);
        return map.getOrDefault(num, num);//没有命中黑名单就直接走default,命中黑名单就走map
    }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(n, blacklist);
 * int param_1 = obj.pick();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值