Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 算法:从未知数组中查找第二小元素的索引_Algorithm_Select - Fatal编程技术网

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)个其他元素进行比较。现在看看哪些元素与最小的元素进行了比较,并找到其中最小的元素

  • 使用两个变量-varminest和var2ndSalest
  • 让人比较数组中的第一个值和第二个值-将索引设置为从小到最小,将另一个设置为var2ndSmallest
  • 按顺序获取下一个索引,并将其命名为varIndexToCheck
  • 比较varIndexToCheck和var2ndSmallest的值-如果varIndexToCheck的值大于var2ndSmallest的值,则转至步骤3
  • 比较varIndexToCheck和varminest的值-如果varIndexToCheck的值大于varminest的值,则设置var2ndSmallest=varIndexToCheck并转至步骤3
  • 否则,设置var2ndSalest=varminest和varminest=varIndexToCheck,然后转到步骤3

  • 重复此操作,直到不再有索引。然后,结果索引在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