【问题标题】:Searching in an array that is first decreasing and then increasing在一个先递减后递增的数组中搜索
【发布时间】:2014-11-05 21:22:28
【问题描述】:

我有一个最初按降序排列的数组。 现在我遍历我的数组中的一个随机索引,在那之后我翻转列表,以便列表的其余部分升序。

现在给出了一个数字,需要找到它的索引。 找到给定数字的索引的有效算法是什么?

例如:

初始列表:50 48 21 15 9 8 7 5 3 2 1

在第 9 位翻转后: 50 48 21 15 1 2 3 5 7 8 9

提供的号码: 21

21 指数 : ?

编辑 1: 有趣的是,列表中以 desc 顺序排列的最小值元素总是大于列表中以升序排列的最大值元素,因为它最初是按降序排列。

【问题讨论】:

  • @interjay 是的,我也这么想,但找不到更好的标题,否则标题会变得太模糊
  • 翻转后 - 数组未排序。如果你想找到索引最好应该是迭代列表并返回匹配元素的索引。
  • @interjay Binary Search 将不起作用,因为必须对该数组进行排序。这里数组翻转后没有排序。
  • 你知道转折点吗?还是您只是翻转后的数组,没有记录翻转的位置?

标签: arrays algorithm sorting


【解决方案1】:

这是this question and answer 的倒数,序列先升后降。在你的情况下,它会下降然后备份。

关键是从找到最小元素的索引开始。一旦你有了它,你可以在左边(减少)部分进行二进制搜索,在右边(增加)部分进行二进制搜索。由于二进制搜索可以在 log time 中完成,因此您可以在 log time 中完成整个操作,前提是您可以找到 log time 中的最小元素。

幸运的是,您也可以通过二分搜索来做到这一点。对于您考虑的数组中的任何位置,如果以下元素更大,则您位于右侧(增加)部分;如果它更小,那么你在左手(减少)部分。这足以让您执行二进制搜索以找到最小值。

【讨论】:

    【解决方案2】:

    在您的情况下,让您的数组长度为 n 13
    在您的情况下,随机索引(翻转点)为 m 4
    在您的情况下,要搜索的数字是 x 21

    If x>= 索引 m-1 的值 // 在你的情况下 21>=15 true
    然后使用二进制搜索从索引 0m-1
    Else
    的数组部分 对数组中从索引 mn-1

    的部分使用二进制搜索

    注意: 翻转后,数组将从 0 下降到翻转点一半,从翻转点上升到数组末尾一半。

    【讨论】:

    • 是的,这就是为什么我问 OP 你是否知道翻转点(m 在你的算法中)。如果是这样,那么可以通过二分查找来完成;但我怀疑答案是否定的。
    • @chiastic-security +1
    【解决方案3】:

    i=0,n为长度,m= n/2x为要搜索的数字和数组是 myArray[]

    IF x> Array[n-1]
    { 
    

    标签 1

      IF myArray[m] < myArray[m+1] 
      { 
        Here we are in the ascendind order and x is not here since x> myArray[n-1]  
        Set n=m and m=n/2  and GOTO LABEL 1.
      }  
      ELSE  
      {  
        Means we are in the descending order.  
        IF x>myArray[m]
        {
          Means x is b/n myArray[0] and myArray[m] therefore, perform binary search in   
        }  
        ELSE
        {
          Means x is b/n myArray[m] and myArray[n-1]
          therefore, set i=m, m=(n-i)/2 and GOTO LABEL 1.  
        }  
      }  
    ELSE  
    

    标签 2

    {  
      IF myArray[m] < myArray[m+1]
      {   
        IF 
        {  
          x < myArray[m] set n=m, m=n/2 and GOTO label 2
        } 
        ELSE  
        {  
          perform binary search b/n myArray[m] and myArray[n-1]    
        } 
      } 
      ELSE
      {  
        set i=m, m=n-i/2 and GOTO LABEL 2 
      } 
    } 
    

    【讨论】:

      【解决方案4】:

      给你..

      var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
      var destination = new int?[source.Length];
      
      var s = new Stopwatch();
      s.Start();
      for (int i = 0; i < 1000000;i++)
      {
      Array.Copy(source, 1, destination, 0, source.Length - 1);
      }
      s.Stop();
      Console.WriteLine(s.Elapsed);
      

      以下是每个解决方案 100 万次迭代的性能结果(8 核 Intel Xeon E5450 @ 3.00GHz)

                                  100 elements    10000 elements
      For Loop                     0.390s         31.839s 
      Array.Copy()                 0.177s         12.496s
      Aaron 1                      3.789s         84.082s
      Array.ConstrainedCopy()      0.197s         17.658s
      

      【讨论】:

      • 这是什么问题的答案?
      猜你喜欢
      • 2018-08-13
      • 2018-04-10
      • 2013-06-18
      • 2017-07-18
      • 2013-06-18
      • 2012-07-17
      • 2019-12-06
      • 1970-01-01
      • 2012-01-02
      相关资源
      最近更新 更多