- 变长数组可以在 O(1) 的时间内完成随机访问元素操作,但是由于无法在 O(1) 的时间内判断元素是否存在,因此不能在 O(1) 的时间内完成插入和删除操作。
- 哈希表可以在 O(1) 的时间内完成插入和删除操作,但是由于无法根据下标定位到特定元素,因此不能在 O(1) 的时间内完成随机访问元素操作。
为了满足插入、删除和随机访问元素操作的时间复杂度都是 O(1),需要将变长数组和哈希表结合,变长数组中存储元素,哈希表中存储每个元素在变长数组中的下标。
class RandomizedSet {
//变长数组
List<Integer> nums;
//哈希表
Map<Integer,Integer> map;
Random random;
/** Initialize your data structure here. */
public RandomizedSet() {
nums = new ArrayList<Integer>();
map = new HashMap<Integer, Integer>();
random = 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;
}
//不存在插入值
int index = nums.size();
nums.add(val);
map.put(val,index);
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 index = map.get(val);
int last = nums.get(nums.size()-1);
map.put(last,index);
nums.set(index,last);
nums.remove(nums.size()-1);
map.remove(val);
return true;
}
/** Get a random element from the set. */
public int getRandom() {
int randomIndex = random.nextInt(nums.size());
return nums.get(randomIndex);
}
}
/**
* 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();
*/