JavaScript中的数据结构,支持Insert,Remove和GetRandomElement

时间:2017-01-05 20:32:42

标签: javascript hashtable

我偶然发现了这个采访问题,我想在JavaScript(而不是Java或C ++)中找到它的解决方案:

  

实现一个类似于set的数据结构,有效地支持Insert,Remove和GetRandomElement。示例:如果插入元素1,3,6,8并删除6,则结构应包含[1,3,8]。现在,GetRandom应该以相同的概率返回1,3或8中的一个。

这在Java中得到了解答:Data structure: insert, remove, contains, get random element, all at O(1)但是,它不提供示例代码。我是初学者,我只是学习如何使用哈希表,所以如果你能解释一下代码,我会很感激!

4 个答案:

答案 0 :(得分:2)

以下是两个简单的解决方案:

第一:

var RandomizedSet = function() {
    this.values = [];
};

RandomizedSet.prototype.insert = function(val) {
    if (this.values.includes(val)) return false;
    this.values.push(val);
    return true;
};

RandomizedSet.prototype.remove = function(val) {
    const idx = this.values.indexOf(val);
    if (idx === -1) return false;
    this.values.splice(idx,1);
    return true;
};

RandomizedSet.prototype.getRandom = function() {
    return this.values[Math.floor(Math.random() * this.values.length)]  ;
};

第二:

var RandomizedSet = function() {
    this.values = {};
    this.length = 0;
};

RandomizedSet.prototype.insert = function(val) {
    if (this.values[val] !== null && this.values[val] !== undefined) return false;
    this.values[val] = val;
    this.length++;
    return true;
};

RandomizedSet.prototype.remove = function(val) {
    if (this.values[val] === null || this.values[val] === undefined) return false;
    delete this.values[val];
    this.length--;
    return true;
};

RandomizedSet.prototype.getRandom = function() {
    return Object.keys(this.values)[Math.floor(Math.random() * this.length)]  ;
};

答案 1 :(得分:1)

您可以使用JavaScript对象。

创建一个对象: var testObject = {};

  1. 插入键/值对
  2. testObject["keyName"] = "value here"; 要么 testObject.keyName = "value here";

    1. 删除密钥
    2. delete testObject["keyName"];

      1. 随机

        function pickRandomProperty(object) {
         var keys = Object.keys(object);
        
         if(keys.length > 0){
            return keys[Math.floor(keys.length * Math.random())];
         }
         else{
            return false;
         }
        }
        

        这将返回一个随机密钥,您可以使用该密钥来获取值: testObject[randomKey]

答案 2 :(得分:0)

假设我们有这些假设:

  • Object.keys not具有恒定的复杂性。
  • 具有持续的复杂性:array.pop()object[key]delete object[key]Math.floor(n)

一种解决方案是跟踪数组中的所有元素及其在对象中的索引。通过这样做,我们可以通过交换它和最后一个来删除元素,然后使用pop函数,假设它具有恒定的复杂性。

'use strict'

function SetStructure () {
  this._length = 0
  this._obj = {}
  this._arr = []
}

SetStructure.prototype.remove = function (el) {
  const idx = this._obj[el]
  if (typeof idx !== 'number') {
    return false
  }
  delete this._obj[el]
  this._arr[idx] = this._arr[this._length-1]
  this._length--
  this._arr.pop()
  return true
}

SetStructure.prototype.insert = function (el) {
  const idx = this._obj[el]
  if (typeof idx === 'number') {
    return false
  }
  this._obj[el] = this._length++
  this._arr.push(el)
  return true
}

SetStructure.prototype.getRandom = function () {
  return this._arr[Math.floor(Math.random() * this._length)]
}


let s = new SetStructure()
s.insert(1)
s.insert(3)
s.insert(6)
s.insert(8)
s.remove(6)

答案 3 :(得分:0)

我最终通过创建一个集数据结构来实现这一目的:

function Set() {

    let items = {};

    this.add = function(value) {
        if (!this.has(value)){
            items[value] = value;
            return true;
        }
        return false;
    };

    this.delete = function(value) {
        if (this.has(value)){
            delete items[value];
            return true;
        }
        return false;
    };

    this.has = function(value) {
        return items.hasOwnProperty(value);
    };

    this.values = function() {
        let values = [];
        for (let i = 0, keys = Object.keys(items); i < keys.length; i++) {
            values.push(items[keys[i]]);
        }
        return values;
    };

    this.getRandomElement = function() {
        var keys = Object.keys(items);
        return items[keys[Math.floor(Math.random() * keys.length)]];
    };
}

相应测试:

let set = new Set();

set.add(1);
set.add(3);
set.add(6);
set.add(8);
console.log(set.values()); 
    // [1, 3, 6, 8];
set.delete(6);
console.log(set.values()); 
    // [1, 3, 8];
console.log(set.getRandomElement());