Leetcode - Insert Delete GetRandom O(1)

My code:

import java.util.*;
public class RandomizedSet {
    private HashMap<Integer, Integer> map; // value -> index
    private ArrayList<Integer> list; // value
    private Random rand;
    /** Initialize your data structure here. */
    public RandomizedSet() {
        map = new HashMap<Integer, Integer>();
        list = new ArrayList<Integer>();
        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 (map.containsKey(val)) {
            return false;
        }
        else {
            map.put(val, list.size());
            list.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 (!map.containsKey(val)) {
            return false;
        }
        else {
            int index = map.remove(val);
            int last = list.remove(list.size() - 1);
            if (last != val) {
                list.set(index, last);
                map.put(last, index);
            }
            return true;
        }
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        int index = rand.nextInt(list.size());
        return list.get(index);
    }
}

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

这道题目没有做出来。但还是很有意思的。
我卡在了这里,
随机返回一个数字。
我的问题是,如果加入了一些数字,有删除了其中一些,然后再随机返回一个数字,如果保证O(1)呢?

看了答案才知道,List + Map

ArrayList 的本质是 Array,
so list.remove(list.size() – 1) -> time complexity is only O(1)

http://stackoverflow.com/questions/24462513/time-complexity-for-java-arraylist-removeelement

The second point is that that the complexity of ArrayList.remove(index)
 is sensitive to the value ofindex
 as well as the list length.
The "advertised" complexity of O(N)
 for the average and worst cases.

In the best case, the complexity is actually O(1)
. Really!
This happens when you remove the last element of the list; i.e. index == list.size() - 1
. That can be performed with zero copying; look at the code that @paxdiablo included in his Answer.

所以先把最后一个元素删了,然后再根据removed value去map里面找index,然后再去list里面,根据index重写该value with last value in list

参考:
https://discuss.leetcode.com/topic/53235/java-with-hashset-arraylist

Anyway, Good luck, Richardo!

My code:

public class RandomizedSet {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    List<Integer> list = new ArrayList<Integer>();
    Random r = new Random();
    /** Initialize your data structure here. */
    public RandomizedSet() {
        
    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    public boolean insert(int val) {
        if (map.containsKey(val)) {
            return false;
        }
        map.put(val, list.size());
        list.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 (!map.containsKey(val)) {
            return false;
        }
        int removedIndex = map.get(val);
        map.remove(val);
        if (removedIndex < list.size() - 1) {
            int tail = list.get(list.size() - 1);
            list.set(removedIndex, tail);
            map.put(tail, removedIndex);
        }
        list.remove(list.size() - 1);
        return true;
    }
    
    /** Get a random element from the set. */
    public int getRandom() {
        return list.get(r.nextInt(list.size()));
    }
}

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

这道题想复杂了。以为 get random 的时候是不允许重复的。但是删除操作是允许重复的。其实不是。所有的都不允许重复。
那就简单了。
HashMap<Integer, Integer> 每个 value 只会对应一个index (在list中)

Anyway, Good luck, Richardo! — 09/30/2016

    原文作者:Richardo92
    原文地址: https://www.jianshu.com/p/a9c2987cd51d#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞