【问题标题】:Can I remove element from array in constant time if I know the index of element that needs to be removed如果我知道需要删除的元素的索引,我可以在恒定时间内从数组中删除元素吗
【发布时间】:2021-12-22 22:20:46
【问题描述】:

我正在尝试在 JavaScript 中实现 hashmap 功能,并希望将所有内容保持在恒定时间内。

问题1:在恒定时间内从数组中删除元素(O(1))我正在使用数组。

问题 2: 解决冲突问题的最佳方法,以防我们为不同的键使用相同的哈希值。

问题 3: 创建哈希码的最佳方式。目前我正在使用每个字符的一些 ASCII 值。

代码示例

class myHashMap {
    constructor(size = 0 ){
        if(size){
            this.hashMap = new Array(size).fill(null);
            this.size = size;
        }
            else{
            this.hashMap = new Array();
            this.size = 0;
            }

    }
    hash(key){

// Here hashing can have collision 
//for example: 122 and 212 will have same hash which is not correct
        let CharArray = key.split("");
       return CharArray.reduce((acc,current) => {
            return acc+current.charCodeAt(0);
        },0);
      
    }
    set(key,value)
    {
        this.size++;
        this.hashMap[this.hash(key)] = value;
    }

    get(key){
        return this.hashMap[key];

    }
    has(key){
        return this.hashMap[key];
    }
    remove(key)
    {

        this.size--;
         this.hashMap.splice(this.hash(key),1); 
      // Here I need to remove element in O(1)
    }
}

【问题讨论】:

  • 向我们展示您迄今为止尝试过的内容,并提供一个最小可重复的示例stackoverflow.com/help/minimal-reproducible-example
  • @wooooooo 我用代码示例更新了问题
  • 只需使用this.hashMap[this.hash(key)] = null;!不要做任何拼接,这会修改数组的大小并将所有元素移动到索引之后(O(n))。
  • "问题 2:解决冲突问题的最佳方法"、"问题 3:创建哈希码的最佳方法" - 请保留为一个每个问题的问题。请注意,维基百科在 resolving hash collisionschoosing good hash functions 上有完整的文章
  • @Faisal "我还需要计算 O(1) 中的哈希值。" - 不,你不需要。或者,您已经这样做了 - O(n) 中的 n 指的是哈希表的大小,而不是键的大小。

标签: javascript arrays performance hashmap time-complexity


【解决方案1】:

问题 1:在恒定时间内从数组中删除元素 (O(1)) 我是 使用数组。

除非您使用“数组”的一些非标准定义,否则您不能在恒定时间内从数组中删除元素。您可以在恒定时间内将项目设置为某个空值。但是“数组”的标准用法是指多个已知大小的项目,它们布置在连续的内存中,以便可以通过指针算法在恒定时间内通过索引访问它们。要从这样的结构中删除一个元素,这意味着数组实际上会变小,您至少需要在要删除的项目之后复制数组中的项目,这是一个 O(n) 操作。

问题 2:如果我们使用相同的哈希值,解决冲突问题的最佳方法 用于不同的键。

没有最好的方法。这个问题有多种解决方案,它们在时间效率、空间、易于实施和其他考虑因素方面做出不同的权衡。两种最常见的大类解决方案是(1)使用“桶”结构,本质上使哈希表成为另一种容器的大部分空实例的数组 - 历史上链表很常见 - 和(2)让该表是平坦的并且通过“开放寻址”来处理冲突,这意味着探测直到您找到一个从哈希索引找到的插槽开始的空插槽。以上,一般来说(1)比较容易实现。

问题 3:创建哈希码的最佳方法。目前我正在使用一些 每个字符的 ASCII 值。

这是一个巨大的主题,但是,是的,您需要使用字符串中字符的数值,问题是您如何处理这些值。查找 C++ 中 boost::hash_combine 的实现示例,其中 there are many references to on StackOverflow

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多