这道题难点在于选择正确的数据结构。如果用array,getrandom和insert很容易O(1), 但是删除不容易O(1)。考虑到这是一个set,数据的顺序无所谓,可以用一个map存储meta信息。

  • arr存储数据
  • map的key是数据值,value是对应的arr的下标

当删除一个数时,

  • copy array中最后一个数到要删除数的位置, 更新map的值,删除要弹出的key, value,最后弹出array的最后一个数。有点狸猫换太子的意思,挺巧妙的。
var RandomizedSet = function() {
    this.map = {};
    this.arr = [];
};

/**
 * Inserts a value to the set. Returns true if the set did not already contain the specified element. 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.insert = function(val) {
    if (val in this.map) {
        return false;
    }
    this.arr.push(val);
    this.map[val] = this.arr.length-1;
    return true;
};

/**
 * Removes a value from the set. Returns true if the set contained the specified element. 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.remove = function(val) {
    if (!(val in this.map)) {
        return false;
    }
    this.arr[this.map[val]] = this.arr[this.arr.length-1];
    this.map[this.arr[this.arr.length-1]] = this.map[val];
    this.arr.pop();
    delete this.map[val];
    return true;
};

/**
 * Get a random element from the set.
 * @return {number}
 */
RandomizedSet.prototype.getRandom = function() {
    return this.arr[Math.floor(Math.random() * this.arr.length)];
};

results matching ""

    No results matching ""