【Leetcode-每日一题】O(1) 时间插入、删除和获取随机元素

O(1) 时间插入、删除和获取随机元素
难度:中等
【Leetcode-每日一题】O(1) 时间插入、删除和获取随机元素_第1张图片
维护一个集合插入删除的问题,容易想到用hashSet,但是需要随机返回一个数的话比较麻烦,使用Random随机一个下标,然后循环到这个下标就返回,本以为会TLE,没想到踩线通过。
代码如下:

public class RandomizedSet{
    Set<Integer> set;
    Random random;

    public RandomizedSet() {
        this.set = new HashSet();
        this.random = new Random();
    }

    public boolean insert(int val) {
        if (set.add(val)){
            return true;
        }else{
            return false;
        }
    }

    public boolean remove(int val) {
        if (set.remove(val)){
            return true;
        }else{
            return false;
        }
    }

    public int getRandom() {
        int i = random.nextInt(set.size());
        int time = 0;
        for (Integer integer : set) {
            if (time==i){
                return integer;
            }
            time++;
        }
        //为了方法不报错,实际不会走这里
        return -1;
    }
}

执行结果:成功
【Leetcode-每日一题】O(1) 时间插入、删除和获取随机元素_第2张图片
优化:可以将哈希表map设计为:以入参 val 为键,数组下标 loc 为值。
维护一个数组 nums,方便后续随机取值
维护一个下标idx,记录当前数组位置(也可以认为是数组长度)。

  • insert操作时,判断map中是否存在,若存在,则返回false,若不存在,则将val与idx以键值对的形式存入map中,再在数组下标idx下记录val。
  • remove操作时,判断map中是否存在,若不存在,则返回false,若存在,则将map中对应的val删除,并获取map对应的value(即为对应的数组下标,记为id),将当前数组最末尾的元素移动到下标为id的位置,并更新map中对应元素的下标。

代码如下:

public class InsertDeleteGetrandomO1 {
    Map<Integer,Integer> map = new HashMap();
    Random random = new Random();
    int[] nums = new int[100000];
    int idx = 0;

    public boolean insert(int val) {
        if (map.containsKey(val)) return false;
        map.put(val,idx);
        nums[idx++] = val;
        return true;
    }

    public boolean remove(int val) {
        if (!map.containsKey(val)) return false;
        //拿到对应下标
        Integer id = map.remove(val);
        //将下标的元素更新为数组最末尾的元素(如果本身是最末尾的元素,则会在下次insert被替换)
        nums[id] = nums[--idx];
        //如果当前元素不是最末尾元素,则需要更新下标。
        if (id!=--idx)
        map.put(nums[idx],id);
        return true;
    }

    public int getRandom() {
        return nums[random.nextInt(map.size())];
    }
}

你可能感兴趣的:(#,LeetCode-每日一题,leetcode)