【问题标题】:Approach to remove element from array in O(1)在 O(1) 中从数组中删除元素的方法
【发布时间】:2019-08-09 12:38:01
【问题描述】:

我正在处理一个非常大的数组,我从中删除了几个元素。到现在为止,每次我想在不知道它的索引的情况下删除一个元素时,我实际上是在做类似的事情:

const newarr = arr.filter(x => x !== y) 

所以,每次我需要删除一个我在O(n) 复杂度中运行的元素时。我认为值得创建一个结构,稍后我可以从 O(1) 的数组中删除一个元素。

出于设计目的,它是一个引用数组,没有重复的元素。

我知道我必须以某种方式创建一个以索引作为值和一些方便的字符串作为键的对象,所以我可以访问O(1) 中的索引并使用以下方法将其删除:

const newarr = [...arr.slice(0, i), ...arr.slice(i + 1, arr.length - 1)]

那么,如何创建这个对象呢?这是一个好方法吗?

【问题讨论】:

  • 不可能在 O(1) 时间内从数组中删除元素。
  • @nickzoum 出于设计目的,必须不修改原始数组,我认为这是主要问题。那么,如果我理解了真正的问题,您需要通过过滤一些元素从现有数组中创建一个 新数组 吗?是吗?
  • 我投票决定将此问题作为离题结束,因为该请求无法满足。
  • “在 C 中,我可以使用 point[er]s 创建这个结构”。不知何故,我对此表示怀疑。您的要求似乎不一致。但是,也许我误解了你的意思。如果您确实有数据结构的 C 实现,请将其放在您的问题中,并询问如何使用 JS 获得类似的功能。
  • @guijob 很抱歉,只要您需要保留原始数组,我认为您不能在O(1) 中这样做,因为您仍然需要遍历数组如果您需要过滤掉项目。此外,您提到不应修改原始数组:在您当前的方法中,切片任一过滤仍保留对旧数组的“引用”,因此,如果您以某种方式更改新数组,旧数组将被更改为嗯,这也是你应该注意的事情。作为旁注,你也不能在 C 中这样做,至少不能以这种方式......

标签: javascript arrays performance


【解决方案1】:

让我们看看数组的一些操作的时间复杂度:

  1. 添加项目是O(1)。由于插入不会移动索引。它只在数组末尾为新项目添加一个新索引
  2. 删除是O(N),因为数组已移位
  3. 按索引删除是O(N),因为需要在更高索引处移动元素
  4. 删除末尾的元素是 O(1),因为没有移位。

所以你需要使用另一种类型的数据结构来删除O(1)

【讨论】:

  • 谢谢。对于这类问题,数组当然不是一个好的数据结构。
  • 伙计,两个问题:1) 你确定要添加O(n) 的项目吗?我问,因为这似乎不那么合乎逻辑。 2) Map.delete()O(1) 吗?
  • 推送到数组是O(1),它只是将新元素放在数组的末尾并更新它的大小
  • @FilipKováč 是的,你是对的!感谢您的精彩评论!我已经编辑了我的回复! :)
【解决方案2】:

聚会有点晚了,但我刚从谷歌来到这里,所以无论谁找到这个线程,到目前为止我找到的 O(1) 队列的最简洁的实现是here。我只是更改了几个错别字并切换到Map 以保持属性的顺序。直播sample 进行测试。

实施

function Queue() {

  this.items = new Map();
  this.tail = 0;
  this.head = 0;

  this.enqueue = (e) => {
    this.items[this.tail++] = e;
  }

  this.dequeue = () => {
    if (this.tail === this.head) return null;
    let e = this.items[this.head];
    delete this.items[this.head++];
    return e;
  }
}

测试

const queue = new Queue();

queue.enqueue("W");
queue.enqueue("A");
queue.enqueue("C");

console.log(queue.items)

for (let i in queue.items) {
    console.log('Iteration => ', i, ' => ', queue.items[i])
}

console.log('Expect W => ', queue.dequeue());
console.log('Expect A => ', queue.dequeue());
console.log('Expect C => ', queue.dequeue());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2021-05-04
    • 2011-10-31
    相关资源
    最近更新 更多