【问题标题】:Searching a number in a rotated sorted Array在旋转排序数组中搜索数字
【发布时间】:2010-12-25 03:02:10
【问题描述】:

给定一个可以旋转的有序数组,以最小的时间复杂度在其中找到一个元素。

eg : 数组内容可以是 [8, 1, 2, 3, 4, 5]。假设您在其中搜索 8。

【问题讨论】:

  • @Thilo:就像数组中的元素可以移动一样,只要它们保持相同的相对顺序(离开一端意味着你只是去另一端)。比如数组[1 2 3 4][2 3 4 1][3 4 1 2][4 1 2 3]都是同一个数组,只是旋转了一圈而已。
  • 当然,您删除了您的评论。但我会留下我的,以防其他人需要澄清。
  • 希腊和@Andrew,我们最初是否知道数组旋转了多少元素?

标签: data-structures


【解决方案1】:

解决方案仍然适用于二进制搜索,因为您需要将数组分成两部分进行检查。

在排序数组中,您只需查看每个部分并确定元素是位于第一部分(我们称之为 A)还是第二部分(B)。由于根据排序数组的定义,分区 A 和 B 将被排序,因此只需对分区边界和搜索键进行一些简单的比较即可。

在一个旋转排序的数组中,只能保证A和B中的一个被排序。如果元素位于已排序的部分内,则解决方案很简单:只需像执行正常的二进制搜索一样执行搜索。但是,如果您必须搜索未排序的部分,则只需在未排序的部分上递归调用您的搜索函数。

这最终给出了 O(lg n) 的时间复杂度。

(实际上,我认为这样的数据结构会附带一个索引,以指示数组已旋转了多少位置。)

编辑:在 Google 上的搜索将我带到 this CodeGuru 上讨论相同问题的有点过时(但正确)的主题。为了补充我的答案,我将复制那里给出的一些伪代码,以便它与我的解决方案一起出现在这里(思路相同):

Search(set):
    if size of set is 1 and set[0] == item 
        return info on set[0]
    divide the set into parts A and B
    if A is sorted and the item is in the A's range
        return Search(A)
    if B is sorted and the item is in the B's range
        return Search(B)
    if A is not sorted
        return Search(A)
    if B is not sorted
        return Search(B)
    return "not found"

【讨论】:

  • +1 表示在实际项目中,将始终维护一个标记。
  • 如何确定一个零件的排序小于 O(n)?
  • 回答我的问题:你只需要比较第一个和最后一个元素。
  • 如果允许元素重复存在 Omega(n) 下限。考虑一个数组,其中除一个元素为 1 外,所有元素均为 0。
【解决方案2】:

O(log(N))

归结为找最大数位置的问题,可以通过检查区域的首末和中间数,递归缩小区域,分治法,这个是O(log(N)) no大于二分查找 O(log(N))。

编辑: 例如,您有

6 7 8 1 2 3 4 5  
^       ^     ^ 

通过查看这 3 个数字,您知道最小/最大数字的位置(稍后将称为标记)在 6 7 8 1 2 的区域内,因此不考虑 3 4 5(通常由移动您的区域开始/结束索引(int)指向数字 6 和 2 )。

下一步,

6 7 8 1 2  
^   ^   ^  

您将再次获得足够的信息来判断标记在哪一侧(左侧或右侧),然后该区域再次缩小到一半(6 7 8)。

这就是想法:我认为你可以改进一个更好的版本,实际上,对于面试来说,带有干净代码的 OK 算法比带有 OK 代码的最佳算法更好:你最好手动-上一些来加热。

祝你好运!

【讨论】:

  • X - 请举例说明您所说的内容。
  • 好的,我看到Andrew给了你代码,结合这里的例子,你应该可以搞定的。
  • 假设输入是6 7 8 1 2 3 4 5,目标是8。这些是上述问题中示例的输入。
  • 反例:在0 1 0 0 0中搜索1。我们不知道应该解雇哪一半。
【解决方案3】:

我最近在一次采访中被问到这个问题。这个问题描述了一种在循环排序数组中搜索“键”的算法。我还被要求编写相同的代码。 这是我想出的:

使用分而治之的二分搜索。 对于每个子数组,检查数组是否已排序。如果排序使用经典的二分搜索 例如

data[start]

    public boolean search(int start,int end){
    int mid =(start+end)/2;
    if(start>end)
    {
        return  false;
    }
    if(data[start]<data[end]){
        return this.normalBinarySearch(start, end);
    }
    else{
        //the other part is unsorted.
        return (this.search(start,mid) ||
        this.search(mid+1,end));
    }
}

normalBinarySearch 是一个简单的二分搜索。

【讨论】:

  • 你需要让 if (arr[start] == number) return true;在 if (start>end) 之后并将 if (start>end) 更改为 if (start>=end)
  • 所以您的代码只返回密钥的存在(true/fasle)。但问题是返回数组中存在的键的实际索引。
【解决方案4】:

它是对普通二分搜索的简单修改。事实上,它适用于旋转数组和排序数组。然而,在排序数组的情况下,它最终会做比实际需要更多的工作。

对于旋转数组,当您将数组拆分为两个子数组时,其中一个子数组可能不按顺序排列。您可以通过比较子数组中的第一个值和最后一个值来轻松检查每一半是否已排序。

知道每个子数组是否已排序,我们可以选择下一步做什么。

1) 左子数组已排序,且值在左子数组范围内(检查两端!)

然后递归搜索左子数组。

2) 右子数组已排序,值在右子数组范围内(检查两端!)

然后递归搜索右子数组。

3) 左侧未排序

然后递归搜索左子数组

4) 右未排序

然后递归搜索右子数组。

注意:这与普通的二分查找的区别在于,我们不能简单地通过比较左子数组的最后一个值(右子数组的第一个值)来选择要递归的子数组来做出决定。该值必须严格在左子数组或右子数组中,并且该子数组必须排序,否则我们必须对未排序的子数组进行递归。

这里有一些实现这个的 Objective-C:

@implementation BinarySearcher

- (BOOL)isValue:(int)value inArray:(int[])array withArraySize:(int)size {

    return [self subSearchArray:array forValue:value fromIndex:0 toIndex:size -1];
}

- (BOOL)subSearchArray:(int[])array forValue:(int)value fromIndex:(int)left toIndex:(int)right {

    if (left <= right) {

        int middle = (left + right) / 2;

        BOOL leftArraySorted = array[left] <= array[middle];
        BOOL rightArraySorted = array[middle + 1] <= array[right];

        if (array[middle] == value) {
            return YES;
        } else if (leftArraySorted && value >= array[left] && value < array[middle]) {
            return [self subSearchArray:array forValue:value fromIndex:left toIndex:middle];
        } else if (rightArraySorted && value >= array[middle + 1] && value <= array[right]) {
            return [self subSearchArray:array forValue:value fromIndex:middle + 1 toIndex:right];
        } else if (!leftArraySorted) {
            return [self subSearchArray:array forValue:value fromIndex:left toIndex:middle];
        } else if (!rightArraySorted) {
            return [self subSearchArray:array forValue:value fromIndex:middle + 1 toIndex:right];
        }
    }

    return NO;
}

@end

【讨论】:

    【解决方案5】:

    在任何索引处,一个分区将被排序,而另一个则未排序。如果key在排序分区内,则在排序数组内搜索,否则在非排序分区内搜索。

    BS(lo, hi)
    m = (lo + hi)/2
    if(k = a[m])
        return m
    b = 0
    if(a[hi] > a[m])
        b = 1
    if(b)
        if(k > a[m] && k<a[hi])
            BS(m+1, hi)
    else
        BS(lo, m-1)
    

    【讨论】:

      【解决方案6】:

      这是我的方法:

      public static int findMin(int[] a, int start, int end){
        int mid = (start + end)/2;
        if(start == mid){
          return a[mid+1];
        }else if(a[start] > a[mid]){
          return findMin(a, start, mid);
        }else if(a[mid+1] > a[start]){
          return findMin(a, mid+1, end);
        }else{
          return a[mid+1];
        }
      }
      

      时间复杂度:O(log n)

      【讨论】:

      • 案例 [4,4,4,4,4,4,4,5,4,4] 失败
      • 是的。我也测试过。当数组中的值加倍时它会失败
      【解决方案7】:

      你可以用一个只暴露的类来包装一个数组

      E get(int index);

      并且将表现为常规排序数组。 例如,如果你有 4 5 1 2 3 4,wrapper.get(0) 将返回 1。

      现在您可以重用二分搜索解决方案。

      包装器看起来像这样:

      class RotatedArrayWrapper<T> {
        int startIndex;
        private final List<T> rotatedArray;
      
        public RotatedArrayWrapper(List<T> rotatedArray) {
          this.rotatedArray = rotatedArray;
          //find index of the smalest element in array
          //keep in mind that there might be duplicates
          startIndex = ... 
        } 
      
        public T get(int index) {
          int size = rotatedArray.size();
          if (index > size) throw Exception...
      
          int actualIndex = (startIndex + index) % size;
          return rotatedArray.get(actualIndex);
        }
      }
      

      【讨论】:

        【解决方案8】:

        Python 实现。可以使用更pythonic:

        from bisect import bisect_left
        
        
        def index(a, x):
            """Binary search to locate the leftmost value exactly equal to x.
            see http://docs.python.org/2/library/bisect.html#searching-sorted-lists
        
            >>> index([5, 14, 27, 40, 51, 70], 27)
            2
            >>> index([1, 2, 3, 4], 10)
            Traceback (most recent call last):
                ...
            ValueError
            """
            i = bisect_left(a, x)
            if i != len(a) and a[i] == x:
                return i
            raise ValueError
        
        
        def _index_shifted(value, sequence, start, stop):
            """Recursive reset location and binary search"""
            # if at reset (min) and it's not the value, it's not there
            if start == stop and sequence[start] != value:
                return -1
            mid = (stop + start) // 2
            # check mid, since we are already here
            if sequence[mid] == value:
                return mid
            # right side is sorted
            elif sequence[mid] < sequence[stop]:
                # if value falls in range, search righ
                if sequence[stop] >= value > sequence[mid]:
                    return index(sequence[mid:stop + 1], value) + mid
                # partition left side
                return _index_shifted(value, sequence, start, mid)
            # left side is sorted
            else:
                # if value falls in range, search left
                if sequence[mid] > value >= sequence[start]:
                    return index(sequence[start:mid], value) + start
                # partition right side
                return _index_shifted(value, sequence, mid + 1, stop)
        
        
        def index_shifted(sequence, value):
            """Returns index of value in a shifted sorted sequence; -1 if not present.
        
            >>> index_shifted([10, 13, 16, 19, 22, 25, 28, 31, 34, 37], 10)
            0
            >>> index_shifted([10, 13, 16, 19, 22, 25, 28, 31, 34, 37], 37)
            9
            >>> index_shifted([34, 37, 10, 13, 16, 19, 22, 25, 28, 31], 10)
            2
            >>> index_shifted([34, 37, 10, 13, 16, 19, 22, 25, 28, 31], 37)
            1
            >>> index_shifted([34, 37, 10, 13, 16, 19, 22, 25, 28, 31], 13)
            3
            >>> index_shifted([34, 37, 10, 13, 16, 19, 22, 25, 28, 31], 25)
            7
            >>> index_shifted([25, 28, 31, 34, 37, 10, 13, 16, 19, 22], 10)
            5
            >>> index_shifted([25, 28, 31, 34, 37, 10, 13, 16, 19, 22], -10)
            -1
            >>> index_shifted([25, 28, 31, 34, 37, 10, 13, 16, 19, 22], 100)
            -1
            """
            return _index_shifted(value, sequence, 0, len(sequence) - 1)
        

        【讨论】:

          【解决方案9】:

          我的解决方案: 效率:O(logn)

          public static int SearchRotatedSortedArray(int l, int d, int[] array, int toFind) {
              if (l >= d) {
                  return -1;
              }
              if (array[l] == toFind) {
                  return l;
              }
              if (array[d] == toFind) {
                  return d;
              }
          
              int mid = (l + d) / 2;
              if (array[mid] == toFind) {
                  return mid;
              }
          
              if ((array[mid] > toFind && toFind > array[l]) || (array[mid] < toFind && array[d] < toFind)) {
                  return SearchRotatedSortedArray(l, mid - 1, array, toFind);
              } else {
                  return SearchRotatedSortedArray(mid + 1, d, array, toFind);
              }
          
          }
          

          【讨论】:

            【解决方案10】:

            //此解决方案使用递归将数组划分为两个相等的子数组,并对单个排序数组应用二进制搜索,然后继续划分未排序数组

            public class SearchRotatedSortedArray
            {
                public static void main(String... args)
                {
                    int[] array={5,6,1,2,3,4};
            
                    System.out.println(search(array,Integer.parseInt(args[0]),0,5));
                }
            
                public static boolean search(int[] array,int element,int start,int end)
                {   
                if(start>=end)
                {
                    if (array[end]==element) return true;else return false;
                }
            
                int mid=(start+end)/2;
                if(array[start]<array[end])
                {
                    return binarySearch(array,element,start,end);
                }
            
                return search(array,element,start,mid)||search(array,element,mid+1,end);    
            }
            
                public static boolean binarySearch(int[] array,int element,int start,int end)
                {
                    int mid;
            
                    while(start<=end)
                    {
                        mid=(start+end)/2;
            
                        if(array[mid]==element)
                        return true;
            
                        if(array[mid]<element)
                        {
                            start=mid+1;
            
                        }
                        else
                        {
                            end=mid-1;
            
                        }
                    }
            
                    return false;
                }
            }
            

            【讨论】:

            • 这里:search(array,element,start,mid)||search(array,element,mid+1,end) 你可以检查要验证的大小
            【解决方案11】:
            int findIndexInRotatedSort( vector<int> input, int s, int e, int toFind )
                {
                    if (s > e || s >= input.size() || e < 0)
                    {
                        return -1;
                    }
            
                    int m = (s + e)/2;
            
                    int sVal = input.at(s);
                    int eVal = input.at(e);
                    int mVal = input.at(m);
            
                    if (sVal == toFind)
                        return s;
                    if (eVal == toFind)
                        return e;
                    if (mVal == toFind)
                        return m;
            
                    bool isFirstOrdered = (sVal < mVal);
                    bool isSecondOrdered = (mVal < eVal);
                    if (toFind > mVal)
                    {
                        if (!isSecondOrdered || toFind < eVal)
                        {
                            return findIndexInRotatedSort( input, m+1, e, toFind );
                        }
                        else
                        {
                            return findIndexInRotatedSort( input, s, m-1, toFind );
                        }
                    }
                    else
                    {
                        if (!isFirstOrdered || toFind > sVal)
                        {
                            return findIndexInRotatedSort( input, s, m-1, toFind );
                        }
                        else
                        {
                            return findIndexInRotatedSort(  input, m+1, e, toFind );
                        }
                    }
                }
            

            【讨论】:

            • 在 *,请不要只是粘贴代码,还要解释您的方法。在这种特定情况下,您可能还需要解释您的答案对已经给出(和接受)的答案的补充。
            【解决方案12】:
            public class RoatatedSorted {
            
            /**
             * @param args
             */
            public static void main(String[] args) {
                // TODO Auto-generated method stub
            
                int[] rotArray = {5,6,7,8,9,10,15,16,17,1,2,3,4,};
            
                search(rotArray,0,rotArray.length-1,10);
            
            }
            
            private static void search(int[] a, int low, int high,int key) {
            
                //int mid =  low + (high-low)/2;
                //if(a[mid]==a[key]){System.out.println("element found at" + key+1 +" position"); return;}
            
                // find pos to split array
                int pos = findSplitIndex(a,low,high);
                System.out.println("split pos found at" + pos +" position");
            
            
                if(key>=a[low]&& key <=a[pos])
                    bsearch(a,low,pos,key);
                if(key>=a[pos+1]&& key <=a[high])
                    bsearch(a,pos+1,high,key);  
            }
            
            
            private static void bsearch(int[] a, int low, int high,int key) {
                // TODO Auto-generated method stub
                if(low>high) return;
                int mid =  low + (high-low)/2;
                if(a[mid]==key)
                {System.out.println("element found at" + ++mid +" position"); return;}
                if(a[mid] > key)
                    bsearch(a,low,mid-1,key);
                if(a[mid]<key)
                    bsearch(a,mid+1,high,key);
            }
            
            private static int findSplitIndex(int[] a, int low, int high) {
                // TODO Auto-generated method stub
                int mid;
                if(low>high)return -1;
                while(true) {
                    mid =  low + (high-low)/2;
                if( a[mid]>a[mid+1])
                break;
            
            
                if(a[mid]>a[low])
                    low=mid;
                if(a[high]>a[mid])
                    high=mid;
            }
                return mid;
            
            
            }
            
            }
            

            【讨论】:

            • 我从来都不是无限循环的粉丝:例如 while(true)。我相信如果将排序数组传递给 findSplitIndex() 可能会卡在这个循环中,因为 mid 将计算中间索引值并且永远不会改变,因此中断永远不会发生。
            【解决方案13】:

            首先找到数组中的最小元素,然后将数组分成两部分。之后使用二叉搜索树搜索给定值。复杂度:O(logn) 如果您必须在旋转数组中找到最小元素,请使用相同的方法,只需跳过二进制搜索。复杂度:O(logn)

            //Search an element in a sorted and pivoted array
                class SearchInPivotedSortedArray
                {
                    //searchInOrtedPivotedArray : Return index of matched element with given value.
                    public static int searchInSortedPivotedArray(int[] A, int value)
                    {
                        int min = findMinElement(A,0,A.Length-1);
                        if (min == A[0])
                           return binarySearchTree(A, 0, A.Length-1, value);
            
            
                        if (value <= A[A.Length-1])
                           return binarySearchTree(A, min, A.Length-1, value);
                        else
                           return binarySearchTree(A, 0, min-1, value);
            
            
                    }
                    //return index of Pivot element
                    public static int findMinElement(int[] Array, int low, int high)
                    {
            
                        if (low >= high)
                            return low;
            
                        int mid = (low + high) / 2;
                        if (mid > low && Array[mid] < Array[mid - 1])
                            return mid;
                        if (mid < high && Array[mid] > Array[mid + 1])
                            return mid + 1;
            
                        if (Array[mid] < Array[high])
                            return findMinElement(Array, low, mid - 1);
            
                        return findMinElement(Array, mid + 1, high);
            
                    }
                    //Return match element index, if not found return -1
                    public static int binarySearchTree(int[] array, int low, int high,int value)
                    {
                        if (low > high)
                            return -1;
                        int mid = (low + high)/2;
            
                        if (array[mid] == value)
                            return mid;
                        if (array[mid] > value)
                            return binarySearchTree(array, low, mid - 1, value);
                        else
                            return binarySearchTree(array, mid + 1, high, value);
            
                    }
                }
            

            【讨论】:

              【解决方案14】:

              这是一个 O(logn) 解决方案:经过测试。它适用于排序和旋转的排序数组:

              public static int rbs(int[] a, int l, int r, int t) {
              
                  if (a[l] <= a[r]) {
                      return bs(a, l, r, t);
                  }
              
                  if (r < l) {
                      return -1;
                  } else {
                      int m = (l+r) / 2;
                      if (a[m] == t) {
                          return m;
                      } else if (a[m] > t) { // check left half
                          if (a[l] > a[m]) { // left is unsorted
                              return rbs(a, l, m-1, t);
                          } else { // left is sorted
                              if (a[l] < t) { // t is in range
                                  return bs(a, l, m-1, t);
                              } else if (a[l] > t) { // t is out of range on left
                                  if (a[r] >= t) {
                                      return rbs (a, m+1, r, t);
                                  } else
                                      return -1;
                              } else
                                  return l;
                          }
                      } else { // other side
                          if (a[r] < a[m]) { // right is unsorted
                              return rbs(a, m+1, r, t);
                          } else { // right is sorted
                              if (a[r] > t) { // t is in range
                                  return bs(a, m+1, r, t);
                              } else if (a[r] < t) { // t is out of range on right side
                                  if (a[l] <= t) {
                                      return rbs (a, l, m-1, t);
                                  } else
                                      return -1;
                              } else
                                  return r;
                          }
                      }
                  }
              }
              
              
              public static int bs(int[] a, int l, int r, int t) {
              
                  int m = (l+r) / 2;
              
                  if (r < l) {
                      return -1;
                  } else {
                      if (a[m] == t)
                          return m;
                      else if (a[m] < t)
                          return bs(a, m+1, r, t);
                      else
                          return bs (a, l, m-1, t);
                  }
              }
              

              【讨论】:

                【解决方案15】:

                试试这个解决方案,

                     public static int findElement(int[] a, int key, int left, int right) {
                
                           if (left > right) {
                              return -1;
                           }
                
                           int mid = (left + right) / 2;
                
                           if (key == a[mid]) {
                              return mid;
                           } else if (key < a[mid]) {
                              return (a[left] <= a[mid] && a[left] < key ? findElement(
                                a, key, left, mid - 1) : findElement(a, key,
                                mid + 1, right));
                           } else {
                              return (a[mid] <= a[right] && a[right] < key ? findElement(
                                a, key, left, mid - 1) : findElement(a, key,
                                mid + 1, right));
                    }
                
                }
                

                【讨论】:

                  【解决方案16】:

                  这是@Andrew Song 答案的 C++ 实现

                  int search(int A[], int s, int e, int k) {
                      if (s <= e) {
                          int m = s + (e - s)/2;
                          if (A[m] == k)
                              return m;
                          if (A[m] < A[e] && k > A[m] && k <= A[e]) 
                              return search(A, m+1, e, k);
                          if (A[m] > A[s] && k < A[m] && k >= A[s]) 
                              return search(A, s, m-1, k);
                          if (A[m] < A[s]) 
                              return search(A, s, m-1, k);
                          if (A[m] > A[e])
                              return search(A, m+1, e, k);
                      }
                      return -1;
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    这是在 PYTHON 中 100% 有效且经过测试的解决方案

                    从已排序但经过旋转的数组中查找数字的程序

                    def findNumber(a, x, start, end):
                      if start > end:
                        return  -1
                      mid = (start + end) / 2
                      if a[mid] == x:
                        return mid
                      ## Case : 1  if a[start] to a[mid] is sorted , then search first half of array
                      if a[start] < a[mid]:
                        if (x >= a[start] and x <= a[mid]):
                          return findNumber(a, x, start, mid - 1)
                        else:
                          return findNumber(a,x, mid + 1, end)
                      ## Case: 2 if a[start] to a[mid] is not sorted , then a[mid] to a[end] mist be sorted
                      else:
                        if (x >= a[mid] and x <= a[end]):
                          return findNumber(a, x, mid + 1, end)
                        else:
                          return findNumber(a,x, start, mid -1)
                    
                    
                    a = [4,5,6,7,0,1,2]
                    print "Your array is  : " , a
                    x = input("Enter any number to find in array : ")
                    result = findNumber(a, x, 0, len(a) - 1)
                    print "The element is present at %d position: ", result
                    

                    【讨论】:

                      【解决方案18】:

                      在最坏的情况下,您必须使用线性搜索并检查整个数组才能找到目标,因为与集合不同,数组可能包含重复项。如果数组包含重复项,则不能在给定问题中使用二进制搜索。

                      如果对特定数组的查询不频繁,如果整个数组已排序(第一个元素严格小于最后一个元素),则可以使用标准二进制搜索,否则使用线性搜索。有关详细信息,请参阅 * 上的 How fast can you make linear search? 讨论和 Thomas A. Limoncelli 的 10 Optimizations on Linear Search 文章。

                      但是,如果查询频繁,您可以在预处理步骤中以线性时间对输入数组进行排序(请参阅 * 上的Fastest algorithm for circle shift N sized array for M position 讨论),并照常使用标准二进制搜索。

                      【讨论】:

                        【解决方案19】:
                        #include<iostream>
                        using namespace std;
                        int BinarySearch(int *a,int key, int length)
                        {
                            int l=0,r=length-1,res=-1;
                            while(l<=r)
                            {
                                int mid = (l+r)/2;
                                if(a[mid] == key) {res = mid; break;}
                                        //Check the part of the array that maintains sort sequence and update index                   
                                        // accordingly.
                                if((a[mid] < a[r] && ( key > a[mid] && key <=a[r]))
                                    || a[mid] > a[r] && !( key>=a[l] && key <a[mid]))
                                {
                                             l = mid+1;
                                }
                                else r = mid-1;
                            }
                            return res;
                        }
                        void main()
                        {
                            int arr[10] = {6,7,8,9,10,13,15,18,2,3};
                            int key = 8;
                            cout<<"Binary Search Output: "<<BinarySearch(arr,key,10);
                        }
                        

                        【讨论】:

                        • 上述程序通过搜索数组中可能包含搜索元素的部分,每次将问题大小除以2。
                        【解决方案20】:

                        在旋转排序数组中查找元素索引

                        Example : [6,7,8,1,2,3,5]
                        
                        int findElementIndex(int []a, int element, int start, int end)
                        {
                            int mid = (start + end)>>1;
                        
                            if(start>end)
                                return -1;
                        
                            if(a[mid] == element)
                            return mid;
                        
                            if(a[mid] < a[start])
                            {
                               if(element <= a[end] && element > a[mid])
                                {
                               return findElementIndex(a,element,mid+1,end);
                                }
                                else{
                               return findElementIndex(a,element,start,mid-1);
                                }
                             }
                            else  if(a[mid] > a[start]){
                                if(element >= a[start] && element < a[mid])
                                     return findElementIndex(a,element,start,mid-1);
                                else
                                    return findElementIndex(a,element,mid+1,end);
                            }
                            else if (a[mid] == a[start]){
                                if(a[mid] != a[end]) // repeated elements
                                  return findElementIndex(a,element,mid+1,end);
                                else
                                    int left = findElementIndex(a,element,start,mid-1);
                                    int right = findElementIndex(a,element,mid+1,end);
                        
                                    return (left != -1) ? left : right;
                        
                            }
                        
                        }
                        

                        【讨论】:

                          最近更新 更多