0
点赞
收藏
分享

微信扫一扫

380. Insert Delete GetRandom O(1)


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

  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 thesame probability

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 2 is the only number in the set, getRandom always return 2. randomSet.getRandom();


思路:
要求插入、删除、随机读取的时间复杂度平均为O(1),注意这里的平均,即题目中的average,并非exactly。这样就能使用HashMap了。看了这道题的Discuss,Discuss里的争论焦点在于能否使用HashMap,要知道,当插入数据遇到冲突时,HashMap的时间复杂度可能降至O(n)。目前主流的观点是,一般情况下HashMap的插入和删除的时间复杂度为O(1),只有当我们遇到散列冲突时,才需要详细分析HashMap时间复杂度。只要能用HashMap,在插入和删除时,我们就可以在O(1)的复杂度下,迅速判断出HashMap内是否包含某个key的键值对。

随机读取元素需要用到类似数组的存储结构,Java中类似的容器是ArrayList。有一个问题需要注意,ArrayList在删除元素时,需要把删除位置后面的元素,依次向前覆盖,最差情况下,时间复杂度降至O(n)。只有在删除最后一个元素时,因为不用移动元素,复杂度为O(1)。因此在删除ArrayList中的某个元素时,可以用最后一个元素替换当前元素,然后删除最后一个元素即可。(当然,此时ArrayList中元素的顺序也发生了变化,最后一个元素被前移了,不过对于本题来讲无所谓,见下图)

380. Insert Delete GetRandom O(1)_复杂度

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Random;

public class RandomizedSet

ArrayList<Integer> arr;
HashMap<Integer, Integer> map;
Random rand;

/** Initialize your data structure here. */
public RandomizedSet() {
arr = new ArrayList<Integer>();
map = new HashMap<Integer, 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) {
boolean contain = map.containsKey(val);
if(!contain) {
map.put(val, arr.size());
arr.add(val);
}
return !contain;
}

/** Removes a value from the set. Returns true if the set contained the specified element. */
public boolean remove(int val) {
boolean contain = map.containsKey(val);
if(contain) {
int index = map.get(val);
int lastIndex = arr.size() - 1;
Integer lastEle = arr.get(lastIndex);
arr.set(index, lastEle);
map.put(lastEle, index);
arr.remove(lastIndex);
map.remove(val);
}
return contain;
}

/** Get a random element from the set. */
public int getRandom() {
int index = rand.nextInt(arr.size());
return arr.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();
*/


举报

相关推荐

0 条评论