Skip to content
On this page

以O(1)时间删除数组元素

本文内容

结合哈希表和数组,使得数组的删除操作时间复杂度也变成 O(1)

实现随机集合

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/*
 * @lc app=leetcode.cn id=380 lang=java
 *
 * [380] O(1) 时间插入、删除和获取随机元素
 */

// @lc code=start
class RandomizedSet {
  private ArrayList<Integer> arr;
  private Map<Integer, Integer> map;
  private Random random = new Random();

  public RandomizedSet() {
    arr = new ArrayList<>();
    map = new HashMap<>();
  }

  public boolean insert(int val) {
    // 如果存在这个值,直接返回false
    if (map.containsKey(val)) {
      return false;
    }
    // 记录val的索引
    map.put(val, arr.size());
    // 把val加入数组中
    arr.add(val);
    return true;
  }

  public boolean remove(int val) {
    // 如果map中不包含这个值,直接返回false
    if (!map.containsKey(val)) {
      return false;
    }
    // 先拿到这个val的索引
    int index = map.get(val);
    // 最后一项的值
    int lastVal = arr.get(arr.size() - 1);
    // 更改最后一项的索引
    map.put(lastVal, index);
    // 将数组中的这一项和最后一项交换
    arr.set(index, lastVal);
    // 移除最后一项
    arr.remove(arr.size() - 1);
    // 在map中移除该值
    map.remove(val);
    return true;
  }

  public int getRandom() {
    return arr.get(random.nextInt(arr.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();
 */
// @lc code=end

避开黑名单的随机数

import java.util.HashMap;
import java.util.Random;

/*
 * @lc app=leetcode.cn id=710 lang=java
 *
 * [710] 黑名单中的随机数
 */

// @lc code=start
class Solution {
  private int sz;
  private HashMap<Integer, Integer> map = new HashMap<>();
  private Random random = new Random();

  public Solution(int n, int[] blacklist) {
    // 计算白名单的数量
    sz = n - blacklist.length;
    // 把黑名单中的元素加入map中
    for (int b : blacklist) {
      map.put(b, 666);
    }

    // 更新黑名单的索引
    int last = n - 1;
    for (int b : blacklist) {
      // 如果b在sz之前,之后的就不需要处理了
      if (b < sz) {
        // 找到最后一个白名单元素的索引
        while (map.containsKey(last)) {
          last--;
        }
        map.put(b, last--);
      }

    }
  }

  public int pick() {
    int index = random.nextInt(sz);
    // 如果index命中黑名单,返回正确的索引,否则直接返回
    return map.getOrDefault(index, index);
  }
}

/**
 * Your Solution object will be instantiated and called as such:
 * Solution obj = new Solution(n, blacklist);
 * int param_1 = obj.pick();
 */
// @lc code=end