算法:从未知数组中查找第二小的元素的索引
我已经思考我的家庭作业问题有一段时间了。我欢迎(并且更喜欢)任何有关如何解决此问题的建议或方法。
基本上,我有一个大小为 N 的数组 A。我们不知道元素,但我们知道它们是不同的。我唯一拥有的是一个会在 N 中取两个索引 (i,j) 的人。然后这个人会告诉我 A[j] 是否 <<或>人工智能]。我想通过向此人询问 <= n + log n 问题来找到查找第二小元素索引的算法。
I have been pondering about my homework question for a while. I welcome (and prefer) any suggestions or approach on how to attack this problem.
Basically, I have an array A of size N. We do not know the elements but we know they are distinct. The only thing that I have is a person who will take two indices (i,j) in N. This person will then tell me whether A[j] is < or > A[i]. I want to find the algorithm for finding the index of the 2nd smallest element by asking <= n + log n questions to this person.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这个答案描述了如何找到第二大元素;可以类似地找到第二小的值。为简单起见,我们还假设所有数字都不同。
为了找到最大的元素,让我们构建一棵“冠军”树:将元素配对,决定哪个更大(那个是“获胜者”),然后将获胜者配对,决定哪个更大,依此类推,直到你找到“冠军”,这是最伟大的元素。这需要n步。现在,第二大要素肯定是与冠军相比。 (因为只有冠军才能击败它)。 log 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 获胜。现在,通过配对元素并选择获胜者,我们构建了一个(有根的二叉)树:
这棵树具有以下属性:对于节点
x
及其子节点y,z
,我们有x>=y, x>=z
,因此我们知道最大的元素是顶部(根部)的元素。我们还知道第二大元素
w
没有到达顶部,因此它在树中有一个父元素。但它的父元素大于或等于w
,因此在树的某个级别,最大元素的子元素之一是w
。 (换句话说,第二大元素只能被最大元素‘击败’)。因此,我们所要做的就是返回最大元素所采取的路径并收集所有直接子元素,我们知道第二大元素就在其中。在我们的例子中,这些是元素 2,5,4 。 (一般来说,大约有log n
个,其中log
表示以 2 为底的对数,因为树的高度约为log n
。) 。从这些元素中,我们使用任何需要log n
步的方法选择最大的元素,然后我们找到了第二大的元素。所有这些可能会让我们想起冠军,其中数字表示每支球队的“优秀”程度,因此有“冠军树”一词。
This answer describes how to find the second greatest element; finding the second smallest can be done analogously. For simplicity, we also assume that all numbers are different.
In order to find the greatest element, let us build a 'championship' tree: pair up the elements, decide which is greater (that one is the 'winner') then pair up the winners, decide which is greater, and so on, until you find the 'champion', which is the greatest element. This takes n steps. Now, the second greatest element must have been compared to the champion. (because only the champion could defeat it). log n elements have been compared to the champion, so from these, pick the greatest; this takes log n steps.
As an example, let us see how this works for the number tuple [6,4,3,5,2,1] . In the first round, pairs are (6,4), (3,5), (2,1). Winners are the greater elements in each pair, that is, 6,5,2. In the second round pairs are (6,5), 2. (2 has no pair here so it will get promoted to the next round automatically). Winners of the second round are 6 and 2, in the third round the only pair is (6,2), 6 is the winner. Now, by pairing up elements and choosing a winner we have built up a (rooted, binary) tree:
This tree has the property that for a node
x
and its childreny,z
we havex>=y, x>=z
, sowe know that the greatest element is the one at the top (at the root). We also know that the second greatest element
w
did not make it to the top, so it has a parent in the tree. But its parent is greater than or equal tow
, so at some level of the tree, one of the children of the greatest element isw
. (In other words, the second greatest element could only be 'defeated' by the greatest element). So all we have to do is go back on the path the greatest element has taken and collect all direct children, we know the second largest is among them. In our case, these are the elements 2,5,4 . (In general, there are aboutlog n
of them, wherelog
denotes base two logarithm, because the tree is aboutlog n
high.). From these elements we pick the largest with any method that takeslog n
steps, and we found the second largest.All this may remind us to a championship, where numbers denote how 'good' each team is, hence the term 'championship tree'.
首先,找到最小的元素。您可以通过 n-1 次比较来实现此目的,即每个元素最多与 log(n) 个其他元素进行比较。现在查看哪些元素与最小元素进行了比较,并找到其中最小的元素。
First, find the smallest element. You can do this with n-1 comaparisons in such a way, that each element is compared to at most log(n) other elements. Now look which elements have been compared to the smallest element and find the smallest of those.
传奇
S 空间复杂度
T 时间复杂度
我是 Arnab Dutta。我有一个发言权...为什么不选择:
所以总 T = O(h)
任何人都可以解释为什么这不比使用
“注意:步骤 1”更好,可以就空间和时间复杂性进行争论。
Legends
S Space Complexity
T Time Complexity
I'm Arnab Dutta. I've a say...why not go for:
So total T = O(h)
Any one having an explanation why this is not better that using
Note: Step 1 can be argued about the Space and Time complexity.
研究排序算法,例如合并排序,其最坏情况复杂度为 O(n log n)。 “人”告诉你是否 A[j] > A[i] true or false 显然是一个比较函数。
合并排序的工作原理是将数组递归地分成两个较小的数组,其大小是原始数组的一半,然后再次对这些数组应用合并排序算法。如果您到达只有一个元素的两个数组的最后一步,您可以要求 person/comparison 函数告诉您如何对这些数组/元素进行排序。从这一步开始,您开始将子数组合并回原来的、但现在已排序的数组。
最后,您可以简单地返回排序数组的第二个元素,这是第二小的元素。
Look into sorting algorithms like merge sort, which has a worst case complexity of O(n log n). The "person" telling you if A[j] > A[i] is true or false is obviously a comparison function.
Merge sort works by recursively dividing your array into two smaller arrays half the size of the original array, then applying the merge sort algorithm to these arrays again. If you arrive at a final step of two arrays with only one element, you ask the person/comparison function to tell you how to sort these arrays/elements. From this step up, you begin to merge your sub-arrays back into your orginal, but now sorted array.
At the end, you can simply return the second element of the sorted array, this being the second smallest.
解决此类问题的最佳方法通常是“分而治之”。即尝试简化/划分问题,解决更简单的问题,然后看看它是否提供了任何有助于您解决原始问题的见解。如果更简单的问题仍然太难,请尝试进一步简化,等等。
在这种情况下,您可以从从数组中查找最小元素开始。你会怎么做?
Attacking such problems is often best done by "divide and conquer". I.e. try to simplify/divide the problem, solve the simpler problem(s), then see if it gave any insight which helps you solving the original question. If the simpler problem is still too hard, try to simplify it further, etc.
In this case, you could start by finding the smallest element from the array. How would you do that?
重复直到没有更多索引。之后,结果索引位于 var2ndSmallest 变量内,复杂度为 O(n log n)
Repeat until there are no more indexes. After that, resulting index is inside var2ndSmallest variable and it is O(n log n) complexity