Tuesday, December 27, 2016

380. Insert Delete GetRandom O(1)

Q:
Design a data structure that supports all following operations in average O(1) time.
  1. insert(val): Inserts an item val to the set if not already present.
  2. remove(val): Removes an item val from the set if present.
  3. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
Example:
// Init an empty set.
RandomizedSet randomSet = new RandomizedSet();

// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1);

// Returns false as 2 does not exist in the set.
randomSet.remove(2);

// Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2);

// getRandom should return either 1 or 2 randomly.
randomSet.getRandom();

// Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1);

// 2 was already in the set, so return false.
randomSet.insert(2);

// Since 1 is the only number in the set, getRandom always return 1.
A:
思路是:   
1:   首先,我们肯定要用Set, 
2:  若想 要 处理getRandom, 需要找到一个数据结构,满足 O(1) 来做getRandom .-----必须要用数组。 (这里我们取巧,用了ArrayList. 如果真用数组的话,就得自己处理resize的问题)  
3:   那么问题来了。   如何处理删掉的呢/???------> 通过检查Set来帮助
       如何处理新增的呢? ----------》  直接加到末尾。
  那么,删除的空间如何利用起来呢?    -------->  Sol 1:   用list保持可以利用的地址。   Sol 2:  每次删掉tail, 把删掉的值,放到该位置。  (这里很容易犯个错,😀,想想是什么?)
            


public class RandomizedSet {
    Set<Integer> set ;
    ArrayList<Integer> posArray ;// use Array to save the values, whenever we find a non-esisting value, we swap with the tail
    /** Initialize your data structure here. */
    public RandomizedSet() {
        set = new HashSet<>();
        posArray = new ArrayList();
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        if(set.contains(val))
            return false;
        set.add(val);
        posArray.add(val); // append at the tail 
        return true;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    public boolean remove(int val) {
        if(set.contains(val)){
            set.remove(val);
            return true;
        }
        return false;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        int index = (int) (Math.random()*posArray.size());
        if( set.contains(posArray.get(index)) ){
            return posArray.get(index);
        }else{ // release this position by swap with the tail
            int tailValue = posArray.remove(posArray.size()-1);
            if(index < posArray.size())// index might already be the tail
                posArray.set(index, tailValue);
            return getRandom();
        }
    }
}

/**
 * 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();
 */

Errors:

由于思路的转换,  临时决定要交换tail, (那么,如果index就是tail呢????)  就出现问题了,哈哈


No comments:

Post a Comment