码迷,mamicode.com
首页 > 其他好文 > 详细

【Leetcode】Insert Delete GetRandom O(1) - Duplicates allowed

时间:2016-08-09 23:26:38      阅读:570      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/

题目:

Design a data structure that supports all following operations in average O(1) time.

Note: Duplicate elements are allowed.

  1. insert(val): Inserts an item val to the collection.
  2. remove(val): Removes an item val from the collection if present.
  3. getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.

Example:

// Init an empty collection.
RandomizedCollection collection = new RandomizedCollection();

// Inserts 1 to the collection. Returns true as the collection did not contain 1.
collection.insert(1);

// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
collection.insert(1);

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
collection.insert(2);

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
collection.getRandom();

// Removes 1 from the collection, returns true. Collection now contains [1,2].
collection.remove(1);

// getRandom should return 1 and 2 both equally likely.
collection.getRandom();

Subscribe to see which companies asked this question

思路:

跟上一题不同点在于允许插入重复元素,我们仍然用list存储插入元素,用hashmap维护元素与下标之间的对应关系,不同点在于我们用一个集合存储某元素所有下标(因为可能有重复元素插入,但它们是按序插入list的即下标是不同的),那么接下来考虑用什么集合存储某元素的所有下标呢?

首先考虑list,但当我们remove某元素时,需要更新某元素的下标集合,此时用list,时间复杂度为O(n)。

考虑set,因为是按序插入list的,即下标是不同的,hashset可以存储,且remove操作时间复杂度为O(1)。

算法:

  /** Initialize your data structure here. */
    public RandomizedCollection() {
        
    }
    List<Integer> vals = new ArrayList<Integer>();
	Map<Integer, Set<Integer>> val2idx = new HashMap<Integer, Set<Integer>>();

    /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
    public boolean insert(int val) {
        boolean flag = false;
        Set<Integer> idxs = null;
        if (val2idx.containsKey(val)) {
            idxs = val2idx.get(val);
			flag=false;
		} else {
		    idxs = new HashSet<Integer>();
			flag=true;
		}
		idxs.add(vals.size());
        vals.add(val);
        val2idx.put(val,idxs);
		return flag;
    }
    
    /** Removes a value from the collection. Returns true if the collection contained the specified element. */
    public boolean remove(int val) {
        if (!val2idx.containsKey(val)) {
			return false;
		} else {
		    Set<Integer> rmIdxs = val2idx.get(val);
		    int rmIdx = rmIdxs.iterator().next();//被删除元素的下标
			if (rmIdx < vals.size() - 1&&val!=vals.get(vals.size()-1)) {//若刪除的不是末尾元素,且被刪除元素不等于末尾元素(若相等的话就当做删除末尾
				// 将末尾元素存入被删除元素的位置,并更新相应下标
				int lastElem = vals.get(vals.size() - 1);//末尾元素
				Set<Integer> lastElemIdxs = val2idx.get(lastElem);//末尾元素的index集合
				lastElemIdxs.remove(vals.size()-1);
				lastElemIdxs.add(rmIdx);
				vals.set(rmIdx,lastElem);
				val2idx.put(lastElem,lastElemIdxs);
			}
			rmIdxs.remove(rmIdx);
			if(rmIdxs.size()==0){
				val2idx.remove(val);
			}else{
				val2idx.put(val,rmIdxs);
			}
			vals.remove(vals.size() - 1);
			return true;
		}
    }
    
   	Random r = new Random();
	public int getRandom() {
		return vals.get(r.nextInt(vals.size()));
	}


【Leetcode】Insert Delete GetRandom O(1) - Duplicates allowed

标签:

原文地址:http://blog.csdn.net/yeqiuzs/article/details/52166689

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!