Algorithm 算法:从未知数组中查找第二小元素的索引
我一直在思考我的家庭作业问题有一段时间了。我欢迎(并且更喜欢)任何关于如何解决这个问题的建议或方法Algorithm 算法:从未知数组中查找第二小元素的索引,algorithm,select,Algorithm,Select,我一直在思考我的家庭作业问题有一段时间了。我欢迎(并且更喜欢)任何关于如何解决这个问题的建议或方法 基本上,我有一个大小为N的数组A。我们不知道元素,但我们知道它们是不同的。我唯一拥有的是一个人,他会在N中取两个指数(I,j)。然后这个人会告诉我a[j]是a[I]。我想通过询问来找到寻找第二小元素索引的算法。攻击此类问题通常最好通过“分而治之”来完成。也就是说,尝试简化/划分问题,解决更简单的问题,然后看看它是否提供了帮助您解决原始问题的见解。如果简单的问题仍然太难,试着进一步简化它,等等 在这
基本上,我有一个大小为N的数组A。我们不知道元素,但我们知道它们是不同的。我唯一拥有的是一个人,他会在N中取两个指数(I,j)。然后这个人会告诉我a[j]是<还是>a[I]。我想通过询问来找到寻找第二小元素索引的算法。攻击此类问题通常最好通过“分而治之”来完成。也就是说,尝试简化/划分问题,解决更简单的问题,然后看看它是否提供了帮助您解决原始问题的见解。如果简单的问题仍然太难,试着进一步简化它,等等
在这种情况下,可以从数组中查找最小的元素开始。您将如何做到这一点?研究像合并排序这样的排序算法,它的最坏情况复杂性为O(n logn)。告诉你A[j]>A[i]是真是假的“人”显然是一个比较函数 合并排序的工作原理是递归地将数组分成两个较小的数组,大小为原始数组的一半,然后再次对这些数组应用合并排序算法。如果到达只有一个元素的两个数组的最后一个步骤,则需要询问person/comparison函数来告诉您如何对这些数组/元素进行排序。从这一步开始,您开始将子数组合并回原始数组,但现在已排序
最后,您只需返回排序数组的第二个元素,它是第二个最小的元素。首先,找到最小的元素。您可以使用n-1个组件来实现这一点,每个元素最多与log(n)个其他元素进行比较。现在看看哪些元素与最小的元素进行了比较,并找到其中最小的元素
重复此操作,直到不再有索引。然后,结果索引在var2ndSalest变量内,它是O(n logn)复杂度这个答案描述了如何找到第二大元素;找到第二个最小值也可以类似地进行。为简单起见,我们还假设所有数字都不同 为了找到最大的元素,让我们建立一个“冠军”树:将元素配对,决定哪个更大(那一个是“赢家”),然后将赢家配对,决定哪个更大,依此类推,直到找到“冠军”,这是最大的元素。这需要n个步骤。现在,第二大元素必须与冠军相比较。(因为只有冠军才能击败它)。对数n元素已与冠军进行了比较,因此从中挑选出最大的元素;这需要logn步骤 作为一个例子,让我们看看这对数字元组[6,4,3,5,2,1]是如何起作用的。在第一轮比赛中,两人分别为(6,4)、(3,5)、(2,1)。优胜者是每对中较大的元素,即6、5、2。在第二轮比赛中,两对分别是(6,5),2。(2在这里没有配对,因此它将自动升级到下一轮)。第二轮的获胜者是6和2,第三轮的唯一一对是(6,2),6是获胜者。现在,通过配对元素并选择赢家,我们建立了一个(有根的二叉树): 此树的属性是,对于节点
x
及其子节点y,z
,我们有x>=y,x>=z
,因此
我们知道最大的元素是位于顶部(根)的元素。我们还知道第二大元素w
没有到达顶部,因此它在树中有一个父元素。但是它的父元素大于或等于w
,因此在树的某个级别上,最大元素的子元素之一是w
。(换句话说,第二大元素只能被最大元素“击败”)。所以我们所要做的就是回到最伟大的元素所走的道路上,收集所有直接的孩子,我们知道第二大的是他们。在我们的例子中,这些是元素2,5,4。(一般来说,大约有logn
,其中log
表示以两个对数为底,因为树大约logn
高。)。从这些元素中,我们用任何采取logn
步骤的方法选择最大的元素,然后我们找到了第二大元素
所有这一切都可能让我们想起一场冠军赛,其中数字表示每支球队的“优秀程度”,因此被称为“冠军树”。
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.
S空间复杂性
时间复杂度
我是阿纳布·杜塔。我有一个说法…为什么不去:
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()]
注意:第1步可以讨论空间和时间的复杂性。那么到目前为止你做了什么?到现在为止,我已经在纸上写了一些模糊随机的小数组,生成了一些I,j对,然后开始计算。我想随机选择一个数字,然后将数组分成两部分,大的和小的。我意识到这将改变数组的索引,现在我正在研究如何让元素保持原样。。。可能只是移动索引?你能修改数组吗?或者分配另一个数组并将元素从
A
移动到该数组?复制的非常类似,如果我理解正确,OP无法重新排列
a. Tournament or
b. using MAX-HEAP