【Lintcode】657. Insert Delete GetRandom O(1)

题目地址:

https://www.lintcode.com/problem/insert-delete-getrandom-o1/description

设计一个数据结构,要求在 O ( 1 ) O(1) O(1)时间内能进行如下操作:
1、插入一个数字(如果该数字已存在,则不插入);
2、删除一个数字;
3、随机返回存储在该数据结构中的数字,要求每个数字取出的概率均等。

思路是,用一个list存数字,用一个map存每个数字对应的下标。这样在插入的时候,先check一下数字是否在map里,如果不在,则插入到list末尾,并且将数字及其下标存进map;删除的时候可以先在map里查一下是否存在,存在的时候,为了实现 O ( 1 ) O(1) O(1)时间内删除,我们可以将要删除的数字移到list末尾再删除,但同时要注意修改一下移动到前面去的数字的下标;getRandom的实现要依赖java的Random类,产生一个随机数作为下标,从list中取出数字返回即可。代码如下:

import java.util.*;

public class RandomizedSet {
    
    private List<Integer> list;
    private Map<Integer, Integer> map;
    private Random random;
    
    public RandomizedSet() {
        // do intialization if necessary
        list = new ArrayList<>();
        map = new HashMap<>();
        random = new Random();
    }
    
    /*
     * @param val: a value to the set
     * @return: true if the set did not already contain the specified element or false
     */
    public boolean insert(int val) {
        // write your code here
        if (map.containsKey(val)) {
            return false;
        }
        
        map.put(val, list.size());
        list.add(val);
        return true;
    }
    
    /*
     * @param val: a value from the set
     * @return: true if the set contained the specified element or false
     */
    public boolean remove(int val) {
        // write your code here
        if (!map.containsKey(val)) {
            return false;
        }
        
        int idx = map.get(val);
        // 如果不在末尾,就将其换到末尾
        if (idx != list.size() - 1) {
            Collections.swap(list, idx, list.size() - 1);
            map.put(list.get(idx), idx);
        }
        
        list.remove(list.size() - 1);
        return true;
    }
    
    /*
     * @return: Get a random element from the set
     */
    public int getRandom() {
        // write your code here
        int ranIdx = random.nextInt(list.size());
        return list.get(ranIdx);
    }
}

所有操作时间复杂度 O ( 1 ) O(1) O(1),空间 O ( n ) O(n) O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值