设计一个查询、删除、随机访问都是O(1)的容器

前言

设计题,为满足查询O(1)可以使用Map,为了使随机访问O(1)可以使用数组存储元素。两种数据结构联动,但是删除O(1)变有了问题,如果删除一个中间元素,则Map里面存的下标全部错乱,此时可以使用最后节点覆盖被删节点来完成下标不错乱。
注:需要注意删除的就是最后一个元素,此时不需要更新map,更新会导致下标越界。

一、案例

在这里插入图片描述

二、题解

package com.xhu.offer.offerII;

import java.util.*;

//插入、删除、随机访问都是O(1)的容器
public class RandomizedSet {
    //Map来O(1)访问+确定下标在那里,数组 + random来O(1)访问。
    //关键问题,如何不让下标整体位移。可以用最后一个值去覆盖,只需要修改最后一个值的下标就可以了。
    Map<Integer, Integer> cache;
    List<Integer> el;
    Random rand;

    /**
     * Initialize your data structure here.
     */
    public RandomizedSet() {
        cache = new HashMap<>();
        el = new ArrayList<>();
        rand = 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 (cache.containsKey(val)) return false;

        cache.put(val, el.size());
        el.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 (!cache.containsKey(val)) return false;

        int idx = cache.get(val);
        cache.remove(val);
        if (el.size() == 1 || el.size() == idx + 1) {
            el.remove(el.size() - 1);
            return true;
        }
        el.remove(idx - 0);
        el.add(idx, el.get(el.size() - 1));
        el.remove(el.size() - 1);
        cache.put(el.get(idx), idx);
        return true;
    }

    /**
     * Get a random element from the set.
     */
    public int getRandom() {
        return el.get(rand.nextInt(el.size()));
    }
}

总结

1)数据结构间相互组合,能够实现丰富的功能。
2)数组删除元素,可以使用最后值覆盖中间删除值来达到O(1)时间复杂度+小标不错位。

参考文献

[1] LeetCode 原题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值