返回轨道
算法 · 2026-05-14 · 19 阅读

P188 支持随机获取元素的集合

算法 19 阅读

信号摘要

难度:Medium · 时长:08:27 · leetcode 380 · lintcode 657

P188 支持随机获取元素的集合

未对外公开播放权限
点击查看说明

描述

这个题目说的是,你要设计一个增加版的集合(Set),它除了支持插入元素(insert)和删除元素(remove)的操作,还能等概率地随机获取当前集合中的元素(getRandom)。并且这 3 个操作的平均时间复杂度都要求是 O(1)。

以下是这个集合的使用示例:

// 初始化一个空集合 RandomizedSet set = new RandomizedSet();

// 成功插入数字 3,返回 true。set: [3] set.insert(3);

// 3 已经存在于集合中,返回 false。set: [3] set.insert(3);

// 成功插入数字 6,返回 true。set: [3, 6] set.insert(6);

// 成功插入数字 9,返回 true。set: [3, 6, 9] set.insert(9);

// 以 1/ 3 的概率返回 3,6 或 9。set: [3, 6, 9] set.getRandom();

// 成功删除数字 3,返回 true。set: [6, 9] set.remove(3);

// 8 不存在于集合中,返回 false。set: [6, 9] set.remove(8);

// 以 1/2 的概率返回 6 或 9。set: [6, 9] set.getRandom();

代码

public class AlgoCasts {

  public class RandomizedSet {

    private final Map<Integer, Integer> map = new HashMap<>();
    private final List<Integer> data = new ArrayList<>();
    private final Random RANDOM = new Random();

    public boolean insert(int val) {
      if (map.containsKey(val)) return false;
      data.add(val);
      map.put(val, data.size()-1);
      return true;
    }

    public boolean remove(int val) {
      if (!map.containsKey(val)) return false;
      int idx = map.get(val);
      int lastVal = data.get(data.size()-1);
      data.set(idx, lastVal);
      data.remove(data.size()-1);
      map.put(lastVal, idx);
      map.remove(val);
      return true;
    }

    public int getRandom() {
      int idx = RANDOM.nextInt(data.size());
      return data.get(idx);
    }
  }

}

📡 通讯频道