【问题标题】:How to dedup an unsorted vector within O(nlogn) while keeping its original order?如何在 O(nlogn) 内对未排序的向量进行去重,同时保持其原始顺序?
【发布时间】:2021-01-29 21:34:39
【问题描述】:

我正在查看数据结构。课本里有一段说

"直接的方法是先排序,然后将其唯一化,就像 排序的向量。这两个步骤都可以在 O(nlogn) 内完成。”

然后

"但是有一个副作用:项目的相对顺序 无法保存。”

终于

“实际上我们可以在不增加 时间复杂度。请自行实施。”

找不到任何线索。在复习课本时,我现在没有使用 STL。我所能想象的就是在合并排序期间尝试改变一些东西。

谁有更明亮的视野?

示例案例

输入:5、3、5、8、5、8、8、8、13

输出:5、3、8、13

【问题讨论】:

  • 您可以在索引[0 1 2 ..i.. n-1] 上创建一个数组,并根据A[i] 的值对其进行排序。然后,您可以使用已排序的索引数组来检测重复项,而无需修改原始 A[] 数组的顺序

标签: c++ algorithm data-structures duplicates time-complexity


【解决方案1】:

一种天真的方法:

  • 构建 std::vector 的副本;在副本中,存储对(元素,索引)而不是简单元素 [复杂度:O(n)];
  • 对副本进行排序[复杂度:O(n log n)];
  • 将副本中的重复项移出到新的数据结构中[复杂度:O(n)];
  • 对于重复数据结构中的每一对(元素,索引),删除原始 std::vector 中该索引处的元素 [复杂度:O(n);例如看问题Erasing multiple objects from a std::vector]

总复杂度:O(n + n log n + n + n) = O(n log n)。排序是最长的一步。

python 中带有基准的替代方法:https://www.peterbe.com/plog/uniqifiers-benchmark(注意:这些替代方法可能与 sort-then-dedup 方法不同 - 例如,一些使用 python 的 set 支持 O(1) 中的成员资格测试)。

另请参阅以下问题:

【讨论】:

  • 不错的尝试兄弟,除了我猜的时间复杂度问题
  • @StevenLiang 你的猜测是悲观的;我编辑了有关时间复杂度的更多信息。
  • 引用的未排序和排序数据结构在我的书中都是向量。该教科书正在谈论C ++中的数据结构。在执行删除步骤时,最坏情况下的最优复杂度可以是 O(n^2)。如果使用链表,在 O(n) 中确实相当容易。
  • 不,如果您小心操作,删除已排序 std::vector 中的重复项是 O(n)。
  • @StevenLiang 实际上,这就是我们首先对其进行排序的原因。从未排序的向量中天真地删除重复项将是 n^2。
猜你喜欢
  • 2019-10-19
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 1970-01-01
  • 2018-04-04
  • 2020-03-08
相关资源
最近更新 更多