【问题标题】:How to find the minimum number that isn't in a set using stl?如何使用stl找到不在集合中的最小数字?
【发布时间】:2016-05-17 00:48:58
【问题描述】:

我有一组正整数。如何找到集合中未包含的最小数字?我可以比 O(n) 更快吗?

例如,我有set s<unsigned int>,我在其中插入和删除了很多数字。现在我知道了它的大小,我想找到最小的数字,而不是在集合中

设置0 1 2 3 4 5 7 9 10 11 14 15
答案是6

【问题讨论】:

  • 你能比检查集合中的每个元素更快吗?
  • 这可能不是最小数字 - 1。对于{1,2,4},答案是3
  • 你能比O(n)更快吗?没有。
  • 如果您知道第一个和最后一个条目和大小,那么您可以知道数字是否丢失或不快速(只要数字不重复)。但是,对于丢失的数字,最坏的情况是 O(n)
  • "通过 O(log n) 更改数据提交的任何方式" - 如果您可以将值存储在排序数组中,那么您可以使用修改后的二进制搜索(通过查看v[i] == i 来检查任意索引之前是否存在间隙)。另一种选择是 - 而不是在仍在搜索的元素范围中途进行二进制探测,您可能会猜到当v[last] - v[first] / (last - first) > 1.0 时,差距在统计上可能更接近范围的开始,但这是否有效取决于您的输入是如何生成的。

标签: c++ stl set


【解决方案1】:

我有一组正整数。如何找到最小的数字 不包含在集合中?

您必须遍历集合中的项目,直到找到不等于(前一个值加一)的值。

我能做到比 O(n) 更快吗?

鉴于上述任务,不,您的一组数字中的第一个“洞”可能在序列中的任何位置,这意味着您需要迭代的项目数,直到您发现该洞成正比到集合中的项目数......即迭代是O(N)。

也就是说,如果允许您在创建数据结构时具有一定的灵活性,您或许能够巧妙地解决问题。例如,您可以从两组开始,而不是建立一组数字——您的原始组,加上第二组,该组始终包含当前未包含在第一组中的任何数字。每当您将一个数字插入第一组时,您就会将其从第二组中删除,反之亦然。然后找到最小缺失数只是读取第二组中的第一个值的问题,这是一个 O(1) 操作。 (当然,这仅在可能的数字范围很小的情况下才实用,否则您的第二组将占用大量内存。如果这是一个问题,您可以通过维护 [min,max] 列表来减少内存使用范围,而不仅仅是单个值,但要维护的代码会变得更复杂一些,并且很可能最终会比原始/天真的 O(n) 解决方案更昂贵)

【讨论】:

    猜你喜欢
    • 2014-02-24
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    相关资源
    最近更新 更多