在经过排序和旋转的数组中搜索


79

在准备面试时,我偶然发现了一个有趣的问题:

您将得到一个经过排序然后旋转的数组。

例如:

  • arr = [1,2,3,4,5]排序
  • 将其向右旋转两次以给出[4,5,1,2,3]

现在,如何最好地在此排序后的旋转数组中进行搜索?

可以取消旋转数组,然后进行二进制搜索。但这并不比在输入数组中进行线性搜索更好,因为两者都是最差情况的O(N)。

请提供一些指示。我为此搜索了很多特殊算法,但找不到任何算法。

我了解C和C ++。


9
如果这是家庭作业,请添加homework标签。这将鼓励人们向您正确的方向轻推,而不是发布可粘贴的答案。
2011年

3
您知道阵列旋转了多少次吗?
Yochai Timmer

2
对于这种大小的阵列,您根本不需要担心。你真正的问题是什么?
2011年

3
不,这不是功课。我不知道转数。该示例保持简单。该数组可以包含数百万个元素。
琼斯

1
数组是否始终具有从1开始的顺序值?还是可以有任何东西(包括重复项)?
原型保罗,

Answers:


207

这可以通过O(logN)使用稍微修改的二进制搜索来完成。

排序+旋转数组的有趣特性是,将数组分为两半时,将始终对这两个半数中的至少一个进行排序。

Let input array arr = [4,5,6,7,8,9,1,2,3]
number of elements  = 9
mid index = (0+8)/2 = 4

[4,5,6,7,8,9,1,2,3]
         ^
 left   mid  right

好像右子数组未排序而左子数组已排序。

如果中点恰好是旋转点,则将对左右两个子数组进行排序。

[6,7,8,9,1,2,3,4,5]
         ^

但是无论如何都必须对一半(子数组)进行排序

通过比较每半的开始和结束元素,我们可以很容易地知道哪半被排序。

一旦找到排序的哪一半,我们就可以看到该一半中是否存在密钥-与极端情况进行简单比较。

如果键在那一半中存在,我们将在另一半中递归调用函数,而
在另一半中则递归调用搜索。

我们在每次调用中都丢弃了一半的数组,从而产生了这种算法O(logN)

伪代码:

function search( arr[], key, low, high)

        mid = (low + high) / 2

        // key not present
        if(low > high)
                return -1

        // key found
        if(arr[mid] == key)
                return mid

        // if left half is sorted.
        if(arr[low] <= arr[mid])

                // if key is present in left half.
                if (arr[low] <= key && arr[mid] >= key) 
                        return search(arr,key,low,mid-1)

                // if key is not present in left half..search right half.
                else                 
                        return search(arr,key,mid+1,high)
                end-if

        // if right half is sorted. 
        else    
                // if key is present in right half.
                if(arr[mid] <= key && arr[high] >= key) 
                        return search(arr,key,mid+1,high)

                // if key is not present in right half..search in left half.
                else
                        return search(arr,key,low,mid-1)
                end-if
        end-if  

end-function

这里的关键是将始终对一个子数组进行排序,使用该子数组可以丢弃该数组的一半。


11
好的解释:)
Arihant Nahata

3
简单。简洁。例子。FTW!
Ashwin

这就是为什么我喜欢Stackoverflow的原因,您总能获得一种解决问题的最佳新方法。感谢@codeaddict
Bharat Soni

3
解决方案中应容纳重复项的变化应该是什么,因为这不会像在“ 15”中搜索重复项那样使数组醒来{10, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
沙达卜·安萨里

4
“排序+旋转数组的有趣特性是,当将其分为两半时,将始终对这两个半数中的至少一个进行排序。” 这使天才或有经验的人与新手分开。谢谢,这一行帮助我可视化了整个解决方案。
wild_nothing

21

当数组中有重复的元素时,可接受的答案有一个错误。例如,arr = {2,3,2,2,2}我们正在寻找3。然后接受答案中的程序将返回-1而不是1。

在“破解编码访谈”一书中详细讨论了该访谈问题。该书中专门讨论了重复元素的条件。由于操作员在评论中说数组元素可以是任何东西,因此我在下面以伪代码给出解决方案:

function search( arr[], key, low, high)

    if(low > high)
        return -1

    mid = (low + high) / 2

    if(arr[mid] == key)
        return mid

    // if the left half is sorted.
    if(arr[low] < arr[mid]) {

        // if key is in the left half
        if (arr[low] <= key && key <= arr[mid]) 
            // search the left half
            return search(arr,key,low,mid-1)
        else
            // search the right half                 
            return search(arr,key,mid+1,high)
        end-if

    // if the right half is sorted. 
    else if(arr[mid] < arr[low])    
        // if the key is in the right half.
        if(arr[mid] <= key && arr[high] >= key) 
            return search(arr,key,mid+1,high)
        else
            return search(arr,key,low,mid-1)
        end-if

    else if(arr[mid] == arr[low])

        if(arr[mid] != arr[high])
            // Then elements in left half must be identical. 
            // Because if not, then it's impossible to have either arr[mid] < arr[high] or arr[mid] > arr[high]
            // Then we only need to search the right half.
            return search(arr, mid+1, high, key)
        else 
            // arr[low] = arr[mid] = arr[high], we have to search both halves.
            result = search(arr, low, mid-1, key)
            if(result == -1)
                return search(arr, mid+1, high, key)
            else
                return result
   end-if
end-function

10
我认为您是唯一一个适当考虑重复元素的人。但是您的方法不能保证对数复杂性。特别是在输入上,例如5,5,5,5,5,5,...(大量修正),5,1,5
西红柿

如果我们重复元素,那么时间复杂度是多少?
Prashanth Debbadwar

我认为如果允许重复则必须是线性的。考虑一个N 1s列表,2某处一个。它可以在任何地方,并且将是有效输入。我们正在寻找那个2。无论我们考虑的M> 2个数字的范围是多少,如果2不在任何一边,我们都无法确定它是否包含在这M个数字中。因此,您无法以任何有帮助的方式缩小搜索范围。
Sopel

18

你可以做2个二进制搜索:首先要找到索引i,使得arr[i] > arr[i+1]

显然,(arr\[1], arr[2], ..., arr[i])(arr[i+1], arr[i+2], ..., arr[n])都是排序数组。

然后,如果是arr[1] <= x <= arr[i],则在第一个数组上执行二进制搜索,否则在第二个数组上执行二进制搜索。

复杂性 O(logN)

编辑: 代码


谢谢麦克斯,但我不明白您将如何申请您的第一个学士学位?
琼斯

我的意思是您的搜索关键字是什么?
琼斯

@Jones,编写代码然后解释变得容易。我编辑了答案,寻找链接。
最大

4
为什么您必须明确搜索“断点”?为什么不直接使用修改后的二进制搜索来搜索元素,而不同时检查“异常”?
ruslik 2011年

我在这里迟到了,有人问我同样的问题,我没有在O(logn)中解决它,我的解决方案对O(n)几乎没有改善。我的方法是两个指针i = 0和j = size()-1,在循环中检查arr [i] ==键或arr [j] ==键,如果发现返回i或j并中断,否则增加i并减1 j,中断条件为i <j,在这种情况下,如果密钥位于中间,则循环将在最坏情况下n / 2个时间运行
Jaydeep Shil

8

我的第一个尝试是使用二进制搜索找到应用的旋转数-这可以通过使用常规的二进制搜索机制在a [n]> a [n + 1]处找到索引n来完成。然后进行常规的二进制搜索,同时对找到的每个移位旋转所有索引。


当您做BS来查找腐烂数目时,您的搜索关键字是什么?
琼斯,

2
@琼斯:这将是一个修改过的二进制搜索。您正在寻找两个相邻值减小的点。猜索引。如果该索引处的值大于数组中的第一个值,则继续在您的猜测的右侧寻找。如果更少,请继续向左看。但是,如果您实际上并不关心不连续性在哪里,而只想执行搜索,则codaddict的答案会更好。
史蒂夫·杰索普

5
int rotated_binary_search(int A[], int N, int key) {
  int L = 0;
  int R = N - 1;

  while (L <= R) {
    // Avoid overflow, same as M=(L+R)/2
    int M = L + ((R - L) / 2);
    if (A[M] == key) return M;

    // the bottom half is sorted
    if (A[L] <= A[M]) {
      if (A[L] <= key && key < A[M])
        R = M - 1;
      else
        L = M + 1;
    }
    // the upper half is sorted
    else {
      if (A[M] < key && key <= A[R])
        L = M + 1;
      else
        R = M - 1;
    }
  }
  return -1;
}

如上所述,这不会处理重复条目的情况。但是,如果元素是唯一的,这是非常简单的代码,因为它不进行任何递归。
kaushal '16

3

如果您知道数组已向右旋转s,则可以简单地执行二进制搜索,将其向右移动s。这是O(lg N)

我的意思是,将s的左极限和(s-1)mod N的右初始化,并在它们之间进行二进制搜索,请注意在正确的区域工作。

如果您不知道旋转了多少数组,则可以使用二元搜索(O(lg N))确定旋转的幅度,然后执行移位二元搜索O(lg N),a总数仍为O(lg N)。


2

如果您知道旋转的程度,您仍然可以进行二进制搜索。

诀窍是获得两个级别的索引:在虚拟0..n-1范围内执行bs,然后在实际查找值时取消旋转它们。


2

对上述帖子的答复:“在'破解编码面试'一书中详细讨论了这个面试问题。书中特别讨论了重复元素的条件。由于操作员在评论中说数组元素可以是任何东西,在下面以伪代码提供我的解决方案:”

您的解决方案是O(n)!(最后一个if条件检查单个条件的数组两半使其成为线性时间复杂度的sol)

我最好进行线性搜索,而不是在编码回合中陷入迷宫般的错误和分段错误。

我不认为有比O(n)更好的解决方案,用于在旋转排序的数组中进行搜索(包含重复项)


2

您不需要先旋转阵列。您可以对旋转后的数组使用二进制搜索(进行一些修改)。

令N为您要搜索的数字:

读取第一个数字(arr [start])和数组中间的数字(arr [end]):

  • 如果arr [start]> arr [end]->前半部分未排序,但后半部分已排序:

    • 如果arr [end]> N->该数字在索引中:(中间+ N-arr [end])

    • 如果N在数组的第一部分重复搜索(请参见结尾在数组的前半部分的中间,依此类推)

(如果第一部分已排序但第二部分未排序,则相同)


1
public class PivotedArray {

//56784321 first increasing than decreasing
public static void main(String[] args) {
    // TODO Auto-generated method stub
    int [] data ={5,6,7,8,4,3,2,1,0,-1,-2};

    System.out.println(findNumber(data, 0, data.length-1,-2));

}

static int findNumber(int data[], int start, int end,int numberToFind){

    if(data[start] == numberToFind){
        return start;
    }

    if(data[end] == numberToFind){
        return end;
    }
    int mid = (start+end)/2;
    if(data[mid] == numberToFind){
        return mid;
    }
    int idx = -1;
    int midData = data[mid];
    if(numberToFind < midData){
        if(midData > data[mid+1]){
            idx=findNumber(data, mid+1, end, numberToFind);
        }else{
            idx =  findNumber(data, start, mid-1, numberToFind);
        }
    }

    if(numberToFind > midData){
        if(midData > data[mid+1]){
            idx =  findNumber(data, start, mid-1, numberToFind);

        }else{
            idx=findNumber(data, mid+1, end, numberToFind);
        }
    }
    return idx;
}

}

1
short mod_binary_search( int m, int *arr, short start, short end)
{

 if(start <= end)
 {
    short mid = (start+end)/2;

    if( m == arr[mid])
        return mid;
    else
    {
        //First half is sorted
        if(arr[start] <= arr[mid])
        {
            if(m < arr[mid] && m >= arr[start])
                return mod_binary_search( m, arr, start, mid-1);
            return mod_binary_search( m, arr, mid+1, end);
        }

        //Second half is sorted
        else
        {
            if(m > arr[mid] && m < arr[start])
                return mod_binary_search( m, arr, mid+1, end);
            return mod_binary_search( m, arr, start, mid-1);
        }
    }
 }
 return -1;
}

1

首先,您需要找到位移常数k。这可以在O(lgN)的时间内完成。从常数移位k中,您可以使用具有常数k的二元搜索轻松找到要查找的元素。增强型二进制搜索也需要O(lgN)时间。总运行时间为O(lgN + lgN)= O(lgN)

为了找到恒定位移,k。您只需要在数组中寻找最小值。数组最小值的索引告诉您恒定位移。考虑排序数组[1,2,3,4,5]。

可能的变化是:
    [1,2,3,4,5] // k = 0
    [5,1,2,3,4] // k = 1
    [4,5,1,2,3] // k = 2
    [3,4,5,1,2] // k = 3
    [2,3,4,5,1] // k = 4
    [1,2,3,4,5] // k = 5%5 = 0 

要在O(lgN)时间内执行任何算法,关键是要始终找到将问题除以一半的方法。一旦这样做,其余的实现细节就很容易

以下是该算法的C ++代码

// This implementation takes O(logN) time
// This function returns the amount of shift of the sorted array, which is
// equivalent to the index of the minimum element of the shifted sorted array. 
#include <vector> 
#include <iostream> 
using namespace std; 

int binarySearchFindK(vector<int>& nums, int begin, int end)
{
    int mid = ((end + begin)/2); 
    // Base cases
    if((mid > begin && nums[mid] < nums[mid-1]) || (mid == begin && nums[mid] <= nums[end]))     
        return mid; 
    // General case 
    if (nums[mid] > nums[end]) 
    {
        begin = mid+1; 
        return binarySearchFindK(nums, begin, end); 
    }
    else
    {
        end = mid -1; 
        return binarySearchFindK(nums, begin, end); 
    }   
}  
int getPivot(vector<int>& nums)
{
    if( nums.size() == 0) return -1; 
    int result = binarySearchFindK(nums, 0, nums.size()-1); 
    return result; 
}

// Once you execute the above, you will know the shift k, 
// you can easily search for the element you need implementing the bottom 

int binarySearchSearch(vector<int>& nums, int begin, int end, int target, int pivot)
{
    if (begin > end) return -1; 
    int mid = (begin+end)/2;
    int n = nums.size();  
    if (n <= 0) return -1; 

    while(begin <= end)
    {
        mid = (begin+end)/2; 
        int midFix = (mid+pivot) % n; 
        if(nums[midFix] == target) 
        {
            return midFix; 
        }
        else if (nums[midFix] < target)
        {
            begin = mid+1; 
        }
        else
        {
            end = mid - 1; 
        }
    }
    return -1; 
}
int search(vector<int>& nums, int target) {
    int pivot = getPivot(nums); 
    int begin = 0; 
    int end = nums.size() - 1; 
    int result = binarySearchSearch(nums, begin, end, target, pivot); 
    return result; 
}
希望这会有所帮助!=)
很快志龙 
多伦多大学 

1

对于具有重复项的旋转数组,如果需要查找元素的第一次出现,则可以使用以下过程(Java代码):

public int mBinarySearch(int[] array, int low, int high, int key)
{
    if (low > high)
        return -1; //key not present

    int mid = (low + high)/2;

    if (array[mid] == key)
        if (mid > 0 && array[mid-1] != key)
            return mid;

    if (array[low] <= array[mid]) //left half is sorted
    {
        if (array[low] <= key && array[mid] >= key)
            return mBinarySearch(array, low, mid-1, key);
        else //search right half
            return mBinarySearch(array, mid+1, high, key);
    }
    else //right half is sorted
    {
        if (array[mid] <= key && array[high] >= key)
            return mBinarySearch(array, mid+1, high, key);
        else
            return mBinarySearch(array, low, mid-1, key);
    }       

}

这是对上述程序的改进。请注意以下其他if条件:

if (mid > 0 && array[mid-1] != key)

0

这是一个不修改原始数组的简单(时间,空间)高效的非递归O(log n)python解决方案。将旋转后的数组切成两半,直到只有两个索引要检查,如果一个索引匹配,则返回正确答案。

def findInRotatedArray(array, num):

lo,hi = 0, len(array)-1
ix = None


while True:


    if hi - lo <= 1:#Im down to two indices to check by now
        if (array[hi] == num):  ix = hi
        elif (array[lo] == num): ix = lo
        else: ix = None
        break

    mid = lo + (hi - lo)/2
    print lo, mid, hi

    #If top half is sorted and number is in between
    if array[hi] >= array[mid] and num >= array[mid] and num <= array[hi]:
        lo = mid

    #If bottom half is sorted and number is in between
    elif array[mid] >= array[lo] and num >= array[lo] and num <= array[mid]:
        hi = mid


    #If top half is rotated I know I need to keep cutting the array down
    elif array[hi] <= array[mid]:
        lo = mid

    #If bottom half is rotated I know I need to keep cutting down
    elif array[mid] <= array[lo]:
        hi = mid

print "Index", ix

0

试试这个解决方案

bool search(int *a, int length, int key)
{
int pivot( length / 2 ), lewy(0), prawy(length);
if (key > a[length - 1] || key < a[0]) return false;
while (lewy <= prawy){
    if (key == a[pivot]) return true;
    if (key > a[pivot]){
        lewy = pivot;
        pivot += (prawy - lewy) / 2 ? (prawy - lewy) / 2:1;}
    else{
        prawy = pivot;
        pivot -= (prawy - lewy) / 2 ? (prawy - lewy) / 2:1;}}
return false;
}

0

C ++中的这段代码适用于所有情况,尽管它适用于重复项,但是如果此代码中有错误,请告诉我。

#include "bits/stdc++.h"
using namespace std;
int searchOnRotated(vector<int> &arr, int low, int high, int k) {

    if(low > high)
        return -1;

    if(arr[low] <= arr[high]) {

        int p = lower_bound(arr.begin()+low, arr.begin()+high, k) - arr.begin();
        if(p == (low-high)+1)
            return -1;
        else
            return p; 
    }

    int mid = (low+high)/2;

    if(arr[low] <= arr[mid]) {

        if(k <= arr[mid] && k >= arr[low])
            return searchOnRotated(arr, low, mid, k);
        else
            return searchOnRotated(arr, mid+1, high, k);
    }
    else {

        if(k <= arr[high] && k >= arr[mid+1])
            return searchOnRotated(arr, mid+1, high, k);
        else
            return searchOnRotated(arr, low, mid, k);
    }
}
int main() {

    int n, k; cin >> n >> k;
    vector<int> arr(n);
    for(int i=0; i<n; i++) cin >> arr[i];
    int p = searchOnRotated(arr, 0, n-1, k);
    cout<<p<<"\n";
    return 0;
}

0

用Java语言编写

var search = function(nums, target,low,high) {
    low= (low || low === 0) ? low : 0;

    high= (high || high == 0) ? high : nums.length -1;

    if(low > high)
        return -1;

    let mid = Math.ceil((low + high) / 2);


    if(nums[mid] == target)
        return mid;

    if(nums[low] < nums[mid]) {
        // if key is in the left half
        if (nums[low] <= target && target <= nums[mid]) 
            // search the left half
            return search(nums,target,low,mid-1);
        else
            // search the right half                 
            return search(nums,target,mid+1,high);
    } else {
        // if the key is in the right half.
        if(nums[mid] <= target && nums[high] >= target) 
            return search(nums,target,mid+1,high)
        else
            return search(nums,target,low,mid-1)
    }
};

输入:nums = [4,5,6,7,0,1,2],目标= 0输出:4


0
import java.util.*;

class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int n=sc.nextInt();
        int arr[]=new int[n];
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;
        int min_index=0,max_index=n;

        for(int i=0;i<n;i++){
            arr[i]=sc.nextInt();
            if(arr[i]>max){
                max=arr[i];
            max_index=i;
            }
            if(arr[i]<min){
                min=arr[i];
                min_index=i;
            }

        }

        int element=sc.nextInt();
        int index;
        if(element>arr[n-1]){
            index=Arrays.binarySearch(arr,0,max_index+1,element);
        }
        else {
             index=Arrays.binarySearch(arr,min_index,n,element);
        }
        if(index>=0){
            System.out.println(index);
        }
        else{
            System.out.println(-1);
        }
    }

}

0

这是我的两分钱:

  • 如果阵列包含重复,可以发现在O(日志(n))的溶液中。正如许多人所证明的那样,可以使用经过调整的二进制搜索版本来查找目标元素。

  • 但是,如果数组包含重复项,我认为无法在O(log(n))中找到目标元素。这是一个示例,说明为什么我认为O(log(n))是不可能的。考虑下面的两个数组:

a = [2,.....................2...........3,6,2......2]
b = [2.........3,6,2........2......................2]

所有点都用数字2填充。您可以看到两个数组都已排序和旋转。如果要考虑二进制搜索,那么他们必须在每次迭代中将搜索域减少一半-这就是我们得到O(log(n))的方式。让我们假设我们正在搜索数字3。在第一种情况下,我们可以看到它隐藏在数组的右侧,而在第二种情况下,它隐藏在数组的第二面。这是我们现阶段对数组的了解:

  • 左= 0
  • 右边=长度-1;
  • 中=左+(右-左)/ 2;
  • arr [mid] = 2;
  • arr [left] = 2;
  • arr [right] = 2;
  • 目标= 3;

这就是我们所拥有的所有信息。我们可以清楚地看到仅作出决定来排除阵列的一半是不够的。结果,唯一的方法是进行线性搜索。我并不是说我们不能优化O(n)时间,我只是说我们不能做到O(log(n))。


0

由于中旬,中期1等,我不喜欢二进制搜索,这就是为什么我总是使用二进制跨步/跳转搜索的原因

如何在旋转数组上使用它?使用两次(一旦找到移位,然后使用.at()查找移位的索引->原始索引)

或比较第一个元素,如果小于第一个元素,则必须在结尾附近

从末尾进行向后跳转搜索,如果找到任何枢轴基准点,则停止

如果是>开始元素,则执行常规的跳转搜索:)


0

使用C#实现

public class Solution {
        public int Search(int[] nums, int target) {
             if (nums.Length == 0) return -1;
                int low = 0;
                int high = nums.Length - 1;
                while (low <= high)
                {
                    int mid = (low + high) / 2;
                    if (nums[mid] == target) return mid;
                    if (nums[low] <= nums[mid]) // 3 4 5 6 0 1 2
                    {
                        if (target >= nums[low] && target <= nums[mid])
                            high = mid;
                        else
                            low = mid + 1;
                    }
                    else // 5 6 0 1 2 3 4
                    {
                        if (target >= nums[mid] && target <= nums[high])
                            low= mid;
                        else
                            high = mid - 1;
                    }
                }
                return -1;
        }
    }

-1

另一种适用于重复值的方法是找到旋转,然后在每次访问数组时应用旋转进行常规的二进制搜索。

test = [3, 4, 5, 1, 2]
test1 = [2, 3, 2, 2, 2]

def find_rotated(col, num):
    pivot = find_pivot(col)
    return bin_search(col, 0, len(col), pivot, num)

def find_pivot(col):
    prev = col[-1]
    for n, curr in enumerate(col):
        if prev > curr:
            return n
        prev = curr
    raise Exception("Col does not seem like rotated array")

def rotate_index(col, pivot, position):
    return (pivot + position) % len(col)

def bin_search(col, low, high, pivot, num):
    if low > high:
        return None
    mid = (low + high) / 2
    rotated_mid = rotate_index(col, pivot, mid)
    val = col[rotated_mid]
    if (val == num):
        return rotated_mid
    elif (num > val):
        return bin_search(col, mid + 1, high, pivot, num)
    else:
        return bin_search(col, low, mid - 1,  pivot, num)

print(find_rotated(test, 2))
print(find_rotated(test, 4))
print(find_rotated(test1, 3))

-1

我的简单代码:-

public int search(int[] nums, int target) {
    int l = 0;
    int r = nums.length-1;
    while(l<=r){
        int mid = (l+r)>>1;
        if(nums[mid]==target){
            return mid;
        }
        if(nums[mid]> nums[r]){
            if(target > nums[mid] || nums[r]>= target)l = mid+1;
            else r = mid-1;
        }
        else{
            if(target <= nums[r] && target > nums[mid]) l = mid+1;
            else r = mid -1;
        }
    }
    return -1;
}

时间复杂度O(log(N))。


-1

问题:在旋转排序数组中搜索

public class SearchingInARotatedSortedARRAY {
    public static void main(String[] args) {
        int[] a = { 4, 5, 6, 0, 1, 2, 3 };

        System.out.println(search1(a, 6));

    }

    private static int search1(int[] a, int target) {
        int start = 0;
        int last = a.length - 1;
        while (start + 1 < last) {
            int mid = start + (last - start) / 2;

            if (a[mid] == target)
                return mid;
            // if(a[start] < a[mid]) => Then this part of the array is not rotated
            if (a[start] < a[mid]) {
                if (a[start] <= target && target <= a[mid]) {
                    last = mid;
                } else {
                    start = mid;
                }
            }
            // this part of the array is rotated
            else {
                if (a[mid] <= target && target <= a[last]) {
                    start = mid;
                } else {
                    last = mid;
                }
            }
        } // while
        if (a[start] == target) {
            return start;
        }
        if (a[last] == target) {
            return last;
        }
        return -1;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.