【问题标题】:The kth great number [closed]第k个大数[关闭]
【发布时间】:2015-03-19 15:13:10
【问题描述】:

我可以使用什么样的数据结构来解决这个问题:

如果输入包含:

  • +1 - 插入值为 Ki 的元素
  • 0 - 查找并打印第 K 个最大元素
  • -1 - 删除值为 Ki 的元素

示例输入:

8
+1 5
+1 3
+1 7
0 2
-1 3
0 1
+1 10
0 3

然后输出:

5
7
5

【问题讨论】:

  • 老实说,您可以使用任何容器。哪个容器最好有待商榷。
  • 一个保持排序的容器。添加/删除元素始终保持排序顺序(从大到小)。找到第 K 个最大的变得微不足道:访问索引 K 处的元素。
  • std::set 可能是最简单的。只是从大到小排序。我不认为性能真的是这里的问题,所以放轻松

标签: c++ data-structures


【解决方案1】:

数据结构:自平衡 BST(例如红黑树)

C++ 中的容器:set

时间复杂度:

  • 插入:O(log(n))
  • 删除:O(log(n))
  • K阶统计:O(n)

【讨论】:

  • 在自平衡 BST 中,通常没有充分的理由说明第 K 个元素需要那么慢。 std::set 让它变得如此缓慢,真实,但是......
  • @Yakk 同意。在纯 RBT 中,您找不到比 O(n) 更快的第 K 个元素,因为您必须遍历树。如果 BST 稍作修改;就像为每个节点添加左子树和右子树中的节点计数器一样,它可以是O(log(n))
【解决方案2】:

我会使用某种形式的二叉搜索树: std::set 可通过密钥访问,看起来完全符合您的需求。 std::map 是一个关联容器,通常实现为红黑树。

在你的情况下,我会选择std::set

//getting the n-th element in set
auto it = std::next(myset.begin(), n);

为了完整起见,我还应该提到 std::vector + std::sort,这在算法上效率较低,但如果您没有庞大的数据集,由于数据局部性(包含向量层),它会更高效在预分配的内存块中以顺序方式存储对象)。

【讨论】:

  • std::set不被索引访问。它是通过密钥访问的。没那么重要,你可以在 O(K) 时间内迭代它,所以..
  • 在输入设置片段时正在考虑蛮力矢量 + 排序解决方案 :) 已修复。
  • 实际上我认为向量解决方案在很多用例中更好。数据局部性超过了每周算法复杂度的小幅增长。周日两次。
  • std::set 并不完全适合。除了std::set 的拟合不精确之外,没有理由找到第 k 个密钥的 O(n) 成本。例如,一个简单的跳过列表将支持 O(lg n) 预期时间内的每个操作,例如,在每个节点上都有计数的 BST 也是如此。 std 两者都没有。
猜你喜欢
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2015-10-06
  • 2016-09-25
相关资源
最近更新 更多