【问题标题】:Min of non-repeating elements in a list, in linear time列表中非重复元素的最小值,在线性时间内
【发布时间】:2018-10-15 05:44:06
【问题描述】:

给定一个未排序的数字列表(可以是 int 或 double),给出算法以在一次遍历列表和线性时间内找到非重复元素的最小值。 (不限空间)

例如

Given list is [2, 7, 9, 5, 2, 8, 3, 5, 1, 5, 6, 1]   
Non-repeating elements are [7, 9, 8, 3, 6]  
Min non-repeating element is 3

我通过创建两个哈希集来尝试这个,一个存储非重复元素,另一个存储重复元素,以及一个变量来存储非重复哈希集的最小值。在少数情况下,这可以给我线性时间,但不是全部。

提前致谢。

【问题讨论】:

  • 它应该为您提供所有情况下的线性复杂性。你能展示你的代码吗?
  • 产生意外结果的特殊情况是什么?列表中的元素是否有任何限制?
  • 这里的不是线性的,是指链表不止一次的遍历吗?
  • 在到达列表末尾之前,您无法知道某个项目是否重复。因此,您不能同时使用一个变量来保存非重复项的最小值,因为在任何时候,都可能证明您的最小值毕竟是重复项。
  • ^ 没错。即使您尝试维护第二个变量来保存 second_minimum,即使这样也可以重复。必须有一些聪明的方法来做到这一点

标签: algorithm list traversal


【解决方案1】:

首先,找到所有不重复的项目,例如带有 key=item 和 value=occurences 的 hashmap。

接下来,遍历 hashmap 并找到 value 为 1 的 min key。

这是线性 O(2n)

【讨论】:

  • 问题明确指出必须在单次遍历中完成-_-
  • 我只遍历列表一次。遍历 hashmap 是不同的。
  • 这是一个很容易陷入的陷阱——我考虑过一种非尾递归方法来解决在递归调用之前添加到哈希图并在递归调用之后比较值直到我意识到的问题它本质上是使用递归堆栈作为第二次遍历。为了保持线性时间,解决这个问题的许多方法似乎都涉及在某种程度上额外遍历列表元素,即使它不那么明显。
  • @SevenStarConstellation OP 说问题中提出的算法“并不总是线性的”。 Ridcully 的 线性的,并且只对原始数组进行一次传递。我觉得这个答案是正确的(或者任何人都可以做到的正确):任何数据结构都会对其收集的数据进行内部传递,因为这就是数据结构 for 的用途:保存数据以供以后高效使用。
  • @tucuxi 够公平的。如果这是在某个时候向 G_S 提出的问题,我不得不承认我很好奇它的“官方”解决方案(如果有的话)是什么。
【解决方案2】:

使用斐波那契堆 (FH) - 带最小值

  • 使堆 \theta(1) 摊销。
  • 在摊销中插入 \theta(1)。
  • Find_Minimum \theta(1) 摊销。
  • Extract_The_Minimum O(log n) 摊销。
  • Increase_Key \theta(1) 摊销。

for i in L
   If i == Find_Min(FH)                // O(1) since the min in the top of the list.
     Increase_key(min(FH), the_max_number)// \theta(1) in amortized.
   else
     Insert(FG)                       // \theta(1) in amortized.
if Find_Min(FH) == the_max_number
   return nil
else
   return Find_Min(FH)

而不是Extract_The_Mininimum,使用设置为 the_max_number 的增加键。

您将在摊销成本中获得 Theta(n)。请参阅 Cormen、Leiserson 和 Rivest 第 3 版的算法简介第 18 章。

【讨论】:

  • 你能澄清一下吗?如果检查当前最小值为 O(1),则 extract-mindecrease-key 不应该是 FH 操作,而不是 extract-maxincrease-key (但在这种情况下,“设置为 @987654327”所指的是什么@")?
  • 在一分钟 FH 中,增加当前最小键是否需要寻找新的最小值(基本上相当于 extract-min 后跟 insert 的新值)?我可能遗漏了一些东西,但看起来Increase_key(min(FH), the_max_number) 仍然会摊销到 O(log n) 而不是 \theta(1),因为如果与增加节点的直接子节点上的decrease_key 相比,保证唯一可能的新最小值是孩子的价值消失了,需要像extract-min一样搜索根。
  • increase_key 未由 extract-min 后跟 insert 实现,参见 CLC
  • 能否请您拼出 CLC 并添加一个链接,比如说,它的亚马逊页面,假设它在网上不合法?我不熟悉缩写词。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2020-05-06
  • 2017-08-26
  • 1970-01-01
  • 2012-10-11
相关资源
最近更新 更多