算法:从未知数组中查找第二个最小元素的索引

时间:2010-09-15 08:34:20

标签: algorithm select

我一直在思考我的家庭作业问题。我欢迎(并且更喜欢)有关如何解决此问题的任何建议或方法。

基本上,我有一个大小为N的数组A.我们不知道这些元素,但我们知道它们是截然不同的。我唯一拥有的是一个人将在N中取两个指数(i,j)。然后这个人会告诉我A [j]是否是<或者> A [i]中。我想通过向这个人询问< = n + log n个问题找到找到第二个最小元素索引的算法。

7 个答案:

答案 0 :(得分:23)

这个答案描述了如何找到第二大元素;找到第二小的可以类似地完成。为简单起见,我们还假设所有数字都不同。

为了找到最好的元素,让我们建立一个'冠军'树:配对元素,决定哪个更大(一个是'赢家')然后配对获胜者,决定哪个更大,以及等等,直到找到'冠军',这是最大的元素。这需要n步。现在,必须将第二大元素与冠军进行比较。 (因为只有冠军才能击败它)。 log n元素已经与冠军相提并论,所以从这些中挑选出最大的;这需要记录步骤。

作为一个例子,让我们看看这对于数字元组[6,4,3,5,2,1]是如何工作的。在第一轮中,对是(6,4),(3,5),(2,1)。获胜者是每对中更大的元素,即6,5,2。在第二轮中,对是(6,5),2。(2在这里没有对,因此它会自动升级到下一轮)。第二轮的获胜者是6和2,在第三轮中唯一的一对是(6,2),6是获胜者。现在,通过配对元素并选择获胜者,我们构建了一个(根,二进制)树:alt text

此树具有以下属性:对于节点x及其子y,z,我们有x>=y, x>=z,因此 我们知道最大元素是顶部(根部)。我们也知道第二个最大的元素w没有到达顶部,所以它在树中有一个父元素。但是它的父级大于或等于w,因此在树的某个级别,最大元素的子级之一是w。 (换句话说,第二大元素只能被最大元素'击败'。因此,我们所要做的就是回到最大元素所采取的路径并收集所有直接的孩子,我们知道其中第二大孩子。在我们的例子中,这些是元素2,5,4。 (一般来说,它们大约有log n,其中log表示基数为2的对数,因为树大约log n。)。从这些元素中我们选择最大的任何方法,采取log n步骤,我们发现第二大。

所有这些都可能让我们想起一个总冠军,其中数字表示每支球队的“好”,因此称为“冠军树”。

答案 1 :(得分:2)

首先,找到最小的元素。您可以使用n-1 comaparisons以这种方式执行此操作,即将每个元素与最多log(n)个其他元素进行比较。现在看看哪些元素与最小元素进行了比较,并找出其中最小元素。

答案 2 :(得分:1)

unknown array = a[].
min1 = a[0].              first element.
min2 = 0.                 can equal anything

for(start at 0, until the end, grow by one):
    if(min1 > a[n]):
      min2 = min1.
      min1 = a[n].

return min2.

答案 3 :(得分:0)

攻击这些问题通常最好通过“分而治之”来完成。即尝试简化/划分问题,解决更简单的问题,然后看看它是否提供了帮助您解决原始问题的任何见解。如果更简单的问题仍然太难,请尝试进一步简化,等等。

在这种情况下,您可以从查找数组中的最小元素开始。你会怎么做?

答案 4 :(得分:0)

查看排序算法,例如合并排序,其最坏情况复杂度为O(n log n)。 “人”告诉你A [j]> A [i]是真或假显然是比较函数。

合并排序的工作原理是将数组递归地划分为原始数组大小的两个较小的数组,然后再将合并排序算法应用于这些数组。如果到达两个只有一个元素的数组的最后一步,则要求person / comparison函数告诉您如何对这些数组/元素进行排序。从这一步开始,您开始将子数组合并回原始但现在已排序的数组。

最后,您可以简单地返回排序数组的第二个元素,这是第二个最小元素。

答案 5 :(得分:0)

  1. 使用2个变量 - varSmallest和var2ndSmallest
  2. 要求人员比较数组中的第一个和第二个值 - 将较小的索引设置为varSmallest,将另一个设置为var2ndSmallest
  3. 按顺序获取下一个索引,并将其命名为varIndexToCheck
  4. 比较varIndexToCheck和var2ndSmallest的值 - 如果varIndexToCheck的值大于var2ndSmallest的值,请转到步骤3
  5. 比较varIndexToCheck和varSmallest的值 - 如果varIndexToCheck的值大于varSmallest的值,则设置var2ndSmallest = varIndexToCheck并转到步骤3
  6. 否则,设置var2ndSmallest = varSmallest和varSmallest = varIndexToCheck然后转到步骤3
  7. 重复直到没有更多索引。之后,结果索引在var2ndSmallest变量内,并且它是O(n log n)复杂度

答案 6 :(得分:0)

图例

空间复杂性 T时间复杂度

我是Arnab Dutta。我有发言权......为什么不去找:

1. maintain the elements as a MIN-HEAP array
                       [S = 0, 
                        T = O(n) if optimized <- ignore as its 1 time activity]
2. call deleteMin() 2 times 
                       [T <= h(tree_height) 
                                   - as internally deleteMin() calls shiftDown()]

总T = O(h)

任何人都有解释为什么这不比使用

更好
     a. Tournament or
     b. using MAX-HEAP

注意:第1步可以讨论空间和时间的复杂性。