Leetcode Insert Delete GetRandom O(1) Duplicates allowed and Not allowed

本文解析了LeetCode上的两道题目:380题要求设计一个支持插入、删除和随机获取元素的数据结构,且所有操作平均时间复杂度为O(1);381题则是380题的升级版,允许重复元素并要求随机返回的元素概率与该元素数量成线性关系。文章详细介绍了如何使用ArrayList和HashMap实现这些要求。

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

Leetcode 381

Design a data structure that supports all following operations in average O(1) time.

Note: Duplicate elements are allowed.

  1. insert(val): Inserts an item val to the collection.
  2. remove(val): Removes an item val from the collection if present.
  3. getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
这道题难在所有的method都必须是 O(1)。
需要一个 ArrayList  来储存所有的数,HashMap 来储存 val 和 HashSet。其中,HashSet里含有 Index。

    List<Integer> l;
    Map<Integer, Set<Integer>> m;
    Random r;
    /** Initialize your data structure here. */
    public RandomizedCollection() {
        l = new ArrayList<>();
        m = new HashMap<>();
        r = new Random();
    }
    
    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    public boolean insert(int val) {
        boolean contains = m.containsKey(val);
        if (!contains) m.put(val, new HashSet<Integer>()); 如果HashMap里没含有val,加入val和与之对应的HashSet
        m.get(val).add(l.size());   找到val,往对应的HashSet里添加index。第一个为0,因为l为空
        l.add(val);
        return !contains;
    }
    
    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    public boolean remove(int val) {
        if (!m.containsKey(val)) return false;
        int idx = m.get(val).iterator().next();  找到与val对应HashSet中的一个index的值
        m.get(val).remove(idx);  从中去除
        if (m.get(val).size() == 0) m.remove(val);
        
        int last = l.remove(l.size() - 1); 从 list 里 去掉最后一项, 用last来表示
        if (idx != l.size()) { 		   判断被去掉的是否是最后一项
            l.set(idx, last);  		   不是的话,把最后一项和被去除的一项交换
            Set<Integer> temp = m.get(last); 得到最后一项的HashSet
            temp.remove(l.size()); 	     去掉最后一项的Index
            temp.add(idx);	           加入被去掉的Index
        }
        return true;
    }
    
    /** Get a random element from the collection. */
    public int getRandom() {
        return l.get(r.nextInt(l.size()));
    }


Leetcode 380

Design a data structure that supports all following operations in average O(1) time.

  1. insert(val): Inserts an item val to the set if not already present.
  2. remove(val): Removes an item val from the set if present.
  3. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.

    Map<Integer, Integer> m;
    List<Integer> l;
    Random r;
    /** Initialize your data structure here. */
    public RandomizedSet() {
        m = new HashMap<>();
        l = new ArrayList<>();
        r = new Random();
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        if (m.containsKey(val)) return false;
        else {
            m.put(val, m.size());
            l.add(val);
            return true;
        }
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        if (!m.containsKey(val)) return false;
        else {
            int i = m.remove(val);   得到被删除val所对应的index
            if (i < l.size() - 1) {  
                l.set(i, l.get(l.size() - 1));  如果不是最后一项的话,就要把最后一项补充到Index的位置
                m.put(l.get(l.size() - 1), i);  把最后一项的值和被删除val所对应的index在HashMap中对应起来
            }
            l.remove(l.size() - 1); 删除最后一项
            return true;
        }
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        return l.get(r.nextInt(l.size()));
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值