📌  相关文章
📜  在经过排序和旋转的数组中搜索元素

📅  最后修改于: 2021-04-23 19:39:14             🧑  作者: Mango

可以通过二进制搜索在O(log n)时间中找到排序数组中的元素。但是,假设我们在您事先不知道的某个枢轴处旋转一个升序排序的数组。因此,例如1 2 3 4 5可能变为3 4 5 1 2。设计一种在O(log n)时间内在旋转数组中查找元素的方法。

sortedPivotedArray

例子:

Input  : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
         key = 3
Output : Found at index 8

Input  : arr[] = {5, 6, 7, 8, 9, 10, 1, 2, 3};
         key = 30
Output : Not found

Input : arr[] = {30, 40, 50, 10, 20}
        key = 10   
Output : Found at index 3

此处提供的所有解决方案均假定数组中的所有元素都是不同的。
基本解决方案:
方法:

  1. 这个想法是找到枢轴点,将数组划分为两个子数组,然后执行二进制搜索。
  2. 查找枢轴的主要思想是–对于排序(按升序排列)和枢轴排列的数组,枢轴元素是唯一一个其下一个元素小于它的元素。
  3. 使用上面的语句,可以找到二进制搜索的枢纽。
  4. 找到枢轴后,将数组分为两个子数组。
  5. 现在,对各个子数组进行了排序,以便可以使用Binary Search来搜索元素。

执行:

Input arr[] = {3, 4, 5, 1, 2}
Element to Search = 1
  1) Find out pivot point and divide the array in two
      sub-arrays. (pivot = 2) /*Index of 5*/
  2) Now call binary search for one of the two sub-arrays.
      (a) If element is greater than 0th element then
             search in left array
      (b) Else Search in right array
          (1 will go in else as 1 < 0th element(3))
  3) If element is found in selected sub-array then return index
     Else return -1.

下面是上述方法的实现:

C++
/* C++ Program to search an element
   in a sorted and pivoted array*/
#include 
using namespace std;
 
/* Standard Binary Search function*/
int binarySearch(int arr[], int low,
                 int high, int key)
{
    if (high < low)
        return -1;
 
    int mid = (low + high) / 2; /*low + (high - low)/2;*/
    if (key == arr[mid])
        return mid;
 
    if (key > arr[mid])
        return binarySearch(arr, (mid + 1), high, key);
 
    // else
    return binarySearch(arr, low, (mid - 1), key);
}
 
/* Function to get pivot. For array 3, 4, 5, 6, 1, 2
   it returns 3 (index of 6) */
int findPivot(int arr[], int low, int high)
{
    // base cases
    if (high < low)
        return -1;
    if (high == low)
        return low;
 
    int mid = (low + high) / 2; /*low + (high - low)/2;*/
    if (mid < high && arr[mid] > arr[mid + 1])
        return mid;
 
    if (mid > low && arr[mid] < arr[mid - 1])
        return (mid - 1);
 
    if (arr[low] >= arr[mid])
        return findPivot(arr, low, mid - 1);
 
    return findPivot(arr, mid + 1, high);
}
 
/* Searches an element key in a pivoted
   sorted array arr[] of size n */
int pivotedBinarySearch(int arr[], int n, int key)
{
    int pivot = findPivot(arr, 0, n - 1);
 
    // If we didn't find a pivot,
    // then array is not rotated at all
    if (pivot == -1)
        return binarySearch(arr, 0, n - 1, key);
 
    // If we found a pivot, then first compare with pivot
    // and then search in two subarrays around pivot
    if (arr[pivot] == key)
        return pivot;
 
    if (arr[0] <= key)
        return binarySearch(arr, 0, pivot - 1, key);
 
    return binarySearch(arr, pivot + 1, n - 1, key);
}
 
/* Driver program to check above functions */
int main()
{
    // Let us search 3 in below array
    int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
    int n = sizeof(arr1) / sizeof(arr1[0]);
    int key = 3;
 
    // Function calling
    cout << "Index of the element is : "
         << pivotedBinarySearch(arr1, n, key);
 
    return 0;
}


C
/* Program to search an element in
   a sorted and pivoted array*/
#include 
 
int findPivot(int[], int, int);
int binarySearch(int[], int, int, int);
 
/* Searches an element key in a pivoted
   sorted array arrp[] of size n */
int pivotedBinarySearch(int arr[], int n, int key)
{
    int pivot = findPivot(arr, 0, n - 1);
 
    // If we didn't find a pivot,
// then array is not rotated at all
    if (pivot == -1)
        return binarySearch(arr, 0, n - 1, key);
 
    // If we found a pivot, then first
// compare with pivot and then
    // search in two subarrays around pivot
    if (arr[pivot] == key)
        return pivot;
    if (arr[0] <= key)
        return binarySearch(arr, 0, pivot - 1, key);
    return binarySearch(arr, pivot + 1, n - 1, key);
}
 
/* Function to get pivot. For array
   3, 4, 5, 6, 1, 2 it returns 3 (index of 6) */
int findPivot(int arr[], int low, int high)
{
    // base cases
    if (high < low)
        return -1;
    if (high == low)
        return low;
 
    int mid = (low + high) / 2; /*low + (high - low)/2;*/
    if (mid < high && arr[mid] > arr[mid + 1])
        return mid;
    if (mid > low && arr[mid] < arr[mid - 1])
        return (mid - 1);
    if (arr[low] >= arr[mid])
        return findPivot(arr, low, mid - 1);
    return findPivot(arr, mid + 1, high);
}
 
/* Standard Binary Search function*/
int binarySearch(int arr[], int low, int high, int key)
{
    if (high < low)
        return -1;
    int mid = (low + high) / 2; /*low + (high - low)/2;*/
    if (key == arr[mid])
        return mid;
    if (key > arr[mid])
        return binarySearch(arr, (mid + 1), high, key);
    return binarySearch(arr, low, (mid - 1), key);
}
 
/* Driver program to check above functions */
int main()
{
    // Let us search 3 in below array
    int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
    int n = sizeof(arr1) / sizeof(arr1[0]);
    int key = 3;
    printf("Index of the element is : %d",
           pivotedBinarySearch(arr1, n, key));
    return 0;
}


Java
/* Java program to search an element
   in a sorted and pivoted array*/
 
class Main {
 
    /* Searches an element key in a
       pivoted sorted array arrp[]
       of size n */
    static int pivotedBinarySearch(int arr[], int n, int key)
    {
        int pivot = findPivot(arr, 0, n - 1);
 
        // If we didn't find a pivot, then
        // array is not rotated at all
        if (pivot == -1)
            return binarySearch(arr, 0, n - 1, key);
 
        // If we found a pivot, then first
        // compare with pivot and then
        // search in two subarrays around pivot
        if (arr[pivot] == key)
            return pivot;
        if (arr[0] <= key)
            return binarySearch(arr, 0, pivot - 1, key);
        return binarySearch(arr, pivot + 1, n - 1, key);
    }
 
    /* Function to get pivot. For array
       3, 4, 5, 6, 1, 2 it returns
       3 (index of 6) */
    static int findPivot(int arr[], int low, int high)
    {
        // base cases
        if (high < low)
            return -1;
        if (high == low)
            return low;
 
        /* low + (high - low)/2; */
        int mid = (low + high) / 2;
        if (mid < high && arr[mid] > arr[mid + 1])
            return mid;
        if (mid > low && arr[mid] < arr[mid - 1])
            return (mid - 1);
        if (arr[low] >= arr[mid])
            return findPivot(arr, low, mid - 1);
        return findPivot(arr, mid + 1, high);
    }
 
    /* Standard Binary Search function */
    static int binarySearch(int arr[], int low, int high, int key)
    {
        if (high < low)
            return -1;
 
        /* low + (high - low)/2; */
        int mid = (low + high) / 2;
        if (key == arr[mid])
            return mid;
        if (key > arr[mid])
            return binarySearch(arr, (mid + 1), high, key);
        return binarySearch(arr, low, (mid - 1), key);
    }
 
    // main function
    public static void main(String args[])
    {
        // Let us search 3 in below array
        int arr1[] = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
        int n = arr1.length;
        int key = 3;
        System.out.println("Index of the element is : "
                           + pivotedBinarySearch(arr1, n, key));
    }
}


Python3
# Python Program to search an element
# in a sorted and pivoted array
 
# Searches an element key in a pivoted
# sorted array arrp[] of size n
def pivotedBinarySearch(arr, n, key):
 
    pivot = findPivot(arr, 0, n-1);
 
    # If we didn't find a pivot,
    # then array is not rotated at all
    if pivot == -1:
        return binarySearch(arr, 0, n-1, key);
 
    # If we found a pivot, then first
    # compare with pivot and then
    # search in two subarrays around pivot
    if arr[pivot] == key:
        return pivot
    if arr[0] <= key:
        return binarySearch(arr, 0, pivot-1, key);
    return binarySearch(arr, pivot + 1, n-1, key);
 
 
# Function to get pivot. For array
# 3, 4, 5, 6, 1, 2 it returns 3
# (index of 6)
def findPivot(arr, low, high):
     
    # base cases
    if high < low:
        return -1
    if high == low:
        return low
     
    # low + (high - low)/2;
    mid = int((low + high)/2)
     
    if mid < high and arr[mid] > arr[mid + 1]:
        return mid
    if mid > low and arr[mid] < arr[mid - 1]:
        return (mid-1)
    if arr[low] >= arr[mid]:
        return findPivot(arr, low, mid-1)
    return findPivot(arr, mid + 1, high)
 
# Standard Binary Search function*/
def binarySearch(arr, low, high, key):
 
    if high < low:
        return -1
         
    # low + (high - low)/2;   
    mid = int((low + high)/2)
     
    if key == arr[mid]:
        return mid
    if key > arr[mid]:
        return binarySearch(arr, (mid + 1), high,
                                            key);
    return binarySearch(arr, low, (mid -1), key);
 
 
# Driver program to check above functions */
# Let us search 3 in below array
arr1 = [5, 6, 7, 8, 9, 10, 1, 2, 3]
n = len(arr1)
key = 3
print("Index of the element is : ",
      pivotedBinarySearch(arr1, n, key))
       
# This is contributed by Smitha Dinesh Semwal


C#
// C# program to search an element
// in a sorted and pivoted array
using System;
 
class main {
 
    // Searches an element key in a
    // pivoted sorted array arrp[]
    // of size n
    static int pivotedBinarySearch(int[] arr,
                                   int n, int key)
    {
        int pivot = findPivot(arr, 0, n - 1);
 
        // If we didn't find a pivot, then
        // array is not rotated at all
        if (pivot == -1)
            return binarySearch(arr, 0, n - 1, key);
 
        // If we found a pivot, then first
        // compare with pivot and then
        // search in two subarrays around pivot
        if (arr[pivot] == key)
            return pivot;
 
        if (arr[0] <= key)
            return binarySearch(arr, 0, pivot - 1, key);
 
        return binarySearch(arr, pivot + 1, n - 1, key);
    }
 
    /* Function to get pivot. For array
    3, 4, 5, 6, 1, 2 it returns
    3 (index of 6) */
    static int findPivot(int[] arr, int low, int high)
    {
        // base cases
        if (high < low)
            return -1;
        if (high == low)
            return low;
 
        /* low + (high - low)/2; */
        int mid = (low + high) / 2;
 
        if (mid < high && arr[mid] > arr[mid + 1])
            return mid;
 
        if (mid > low && arr[mid] < arr[mid - 1])
            return (mid - 1);
 
        if (arr[low] >= arr[mid])
            return findPivot(arr, low, mid - 1);
 
        return findPivot(arr, mid + 1, high);
    }
 
    /* Standard Binary Search function */
    static int binarySearch(int[] arr, int low,
                            int high, int key)
    {
        if (high < low)
            return -1;
 
        /* low + (high - low)/2; */
        int mid = (low + high) / 2;
 
        if (key == arr[mid])
            return mid;
        if (key > arr[mid])
            return binarySearch(arr, (mid + 1), high, key);
 
        return binarySearch(arr, low, (mid - 1), key);
    }
 
    // Driver Code
    public static void Main()
    {
        // Let us search 3 in below array
        int[] arr1 = { 5, 6, 7, 8, 9, 10, 1, 2, 3 };
        int n = arr1.Length;
        int key = 3;
        Console.Write("Index of the element is : "
                      + pivotedBinarySearch(arr1, n, key));
    }
}
 
// This code is contributed by vt_m.


PHP
 $arr[$mid])
        return binarySearch($arr, ($mid + 1),
                                $high, $key);
         
    else
        return binarySearch($arr, $low,
                      ($mid -1), $key);
}
 
// Function to get pivot.
// For array 3, 4, 5, 6, 1, 2
// it returns 3 (index of 6)
function findPivot($arr, $low, $high)
{
     
    // base cases
    if ($high < $low)
        return -1;
    if ($high == $low)
        return $low;
     
    /*low + (high - low)/2;*/
    $mid = ($low + $high)/2;
    if ($mid < $high and $arr[$mid] >
                     $arr[$mid + 1])
        return $mid;
         
    if ($mid > $low and $arr[$mid] <
                    $arr[$mid - 1])
        return ($mid - 1);
         
    if ($arr[$low] >= $arr[$mid])
        return findPivot($arr, $low,
                          $mid - 1);
         
    return findPivot($arr, $mid + 1, $high);
}
 
// Searches an element key
// in a pivoted sorted array
// arr[] of size n */
function pivotedBinarySearch($arr, $n, $key)
{
    $pivot = findPivot($arr, 0, $n - 1);
     
    // If we didn't find a pivot,
    // then array is not rotated
    // at all
    if ($pivot == -1)
        return binarySearch($arr, 0,
                       $n - 1, $key);
     
    // If we found a pivot,
    // then first compare
    // with pivot and then
    // search in two subarrays
    // around pivot
    if ($arr[$pivot] == $key)
        return $pivot;
         
    if ($arr[0] <= $key)
        return binarySearch($arr, 0,
                   $pivot - 1, $key);
         
        return binarySearch($arr, $pivot + 1,
                                $n - 1, $key);
}
 
// Driver Code
// Let us search 3
// in below array
$arr1 = array(5, 6, 7, 8, 9, 10, 1, 2, 3);
$n = count($arr1);
$key = 3;
 
// Function calling
echo "Index of the element is : ",
      pivotedBinarySearch($arr1, $n, $key);
             
// This code is contributed by anuj_67.
?>


C++
// Search an element in sorted and rotated
// array using single pass of Binary Search
#include 
using namespace std;
 
// Returns index of key in arr[l..h] if
// key is present, otherwise returns -1
int search(int arr[], int l, int h, int key)
{
    if (l > h)
        return -1;
 
    int mid = (l + h) / 2;
    if (arr[mid] == key)
        return mid;
 
    /* If arr[l...mid] is sorted */
    if (arr[l] <= arr[mid]) {
        /* As this subarray is sorted, we can quickly
        check if key lies in half or other half */
        if (key >= arr[l] && key <= arr[mid])
            return search(arr, l, mid - 1, key);
        /*If key not lies in first half subarray,
           Divide other half  into two subarrays,
           such that we can quickly check if key lies
           in other half */
        return search(arr, mid + 1, h, key);
    }
 
    /* If arr[l..mid] first subarray is not sorted, then arr[mid... h]
    must be sorted subarray */
    if (key >= arr[mid] && key <= arr[h])
        return search(arr, mid + 1, h, key);
 
    return search(arr, l, mid - 1, key);
}
 
// Driver program
int main()
{
    int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int key = 6;
    int i = search(arr, 0, n - 1, key);
 
    if (i != -1)
        cout << "Index: " << i << endl;
    else
        cout << "Key not found";
}


Java
/* Java program to search an element in
   sorted and rotated array using
   single pass of Binary Search*/
 
class Main {
    // Returns index of key in arr[l..h]
    // if key is present, otherwise returns -1
    static int search(int arr[], int l, int h, int key)
    {
        if (l > h)
            return -1;
 
        int mid = (l + h) / 2;
        if (arr[mid] == key)
            return mid;
 
        /* If arr[l...mid] first subarray is sorted */
        if (arr[l] <= arr[mid]) {
            /* As this subarray is sorted, we
               can quickly check if key lies in
               half or other half */
            if (key >= arr[l] && key <= arr[mid])
                return search(arr, l, mid - 1, key);
            /*If key not lies in first half subarray,
           Divide other half  into two subarrays,
           such that we can quickly check if key lies
           in other half */
            return search(arr, mid + 1, h, key);
        }
 
        /* If arr[l..mid] first subarray is not sorted,
           then arr[mid... h] must be sorted subarry*/
        if (key >= arr[mid] && key <= arr[h])
            return search(arr, mid + 1, h, key);
 
        return search(arr, l, mid - 1, key);
    }
 
    // main function
    public static void main(String args[])
    {
        int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
        int n = arr.length;
        int key = 6;
        int i = search(arr, 0, n - 1, key);
        if (i != -1)
            System.out.println("Index: " + i);
        else
            System.out.println("Key not found");
    }
}


Python3
# Search an element in sorted and rotated array using
# single pass of Binary Search
 
# Returns index of key in arr[l..h] if key is present,
# otherwise returns -1
def search (arr, l, h, key):
    if l > h:
        return -1
     
    mid = (l + h) // 2
    if arr[mid] == key:
        return mid
 
    # If arr[l...mid] is sorted
    if arr[l] <= arr[mid]:
 
        # As this subarray is sorted, we can quickly
        # check if key lies in half or other half
        if key >= arr[l] and key <= arr[mid]:
            return search(arr, l, mid-1, key)
        return search(arr, mid + 1, h, key)
 
    # If arr[l..mid] is not sorted, then arr[mid... r]
    # must be sorted
    if key >= arr[mid] and key <= arr[h]:
        return search(a, mid + 1, h, key)
    return search(arr, l, mid-1, key)
 
# Driver program
arr = [4, 5, 6, 7, 8, 9, 1, 2, 3]
key = 6
i = search(arr, 0, len(arr)-1, key)
if i != -1:
    print ("Index: % d"% i)
else:
    print ("Key not found")
 
# This code is contributed by Shreyanshi Arun


C#
/* C# program to search an element in
sorted and rotated array using
single pass of Binary Search*/
using System;
 
class GFG {
 
    // Returns index of key in arr[l..h]
    // if key is present, otherwise
    // returns -1
    static int search(int[] arr, int l, int h,
                      int key)
    {
        if (l > h)
            return -1;
 
        int mid = (l + h) / 2;
 
        if (arr[mid] == key)
            return mid;
 
        /* If arr[l...mid] is sorted */
        if (arr[l] <= arr[mid]) {
 
            /* As this subarray is sorted, we
            can quickly check if key lies in
            half or other half */
            if (key >= arr[l] && key <= arr[mid])
                return search(arr, l, mid - 1, key);
 
            return search(arr, mid + 1, h, key);
        }
 
        /* If arr[l..mid] is not sorted,
        then arr[mid... r] must be sorted*/
        if (key >= arr[mid] && key <= arr[h])
            return search(arr, mid + 1, h, key);
 
        return search(arr, l, mid - 1, key);
    }
 
    // main function
    public static void Main()
    {
        int[] arr = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
        int n = arr.Length;
        int key = 6;
        int i = search(arr, 0, n - 1, key);
 
        if (i != -1)
            Console.WriteLine("Index: " + i);
        else
            Console.WriteLine("Key not found");
    }
}
 
// This code is contributed by anuj_67.


PHP
 $h) return -1;
 
    $mid = ($l + $h) / 2;
    if ($arr[$mid] == $key)
        return $mid;
 
    /* If arr[l...mid] is sorted */
    if ($arr[$l] <= $arr[$mid])
    {
         
        /* As this subarray is
           sorted, we can quickly
           check if key lies in
           half or other half */
        if ($key >= $arr[$l] &&
            $key <= $arr[$mid])
                return search($arr, $l,
                       $mid - 1, $key);
 
        return search($arr, $mid + 1,
                           $h, $key);
    }
 
    /* If arr[l..mid] is not
       sorted, then arr[mid... r]
       must be sorted*/
    if ($key >= $arr[$mid] &&
          $key <= $arr[$h])
        return search($arr, $mid + 1,
                            $h, $key);
 
    return search($arr, $l,
             $mid-1, $key);
}
 
    // Driver Code
    $arr = array(4, 5, 6, 7, 8, 9, 1, 2, 3);
    $n = sizeof($arr);
    $key = 6;
    $i = search($arr, 0, $n-1, $key);
 
    if ($i != -1)
        echo "Index: ", floor($i), " \n";
    else
        echo "Key not found";
 
// This code is contributed by ajit
?>


Javascript


输出:

Index of the element is : 8

复杂度分析:

  • 时间复杂度: O(log n)。
    二进制搜索需要log n比较才能找到元素。因此,时间复杂度为O(log n)。
  • 空间复杂度: O(1),不需要额外的空间。

感谢Ajay Mishra提出的初步解决方案。
改进的解决方案:
方法:可以在一遍二分查找中找到结果,而不是二遍或二遍以上的二分查找。需要修改二进制搜索以执行搜索。这个想法是创建一个递归函数,该函数以l和r作为输入和键的范围。

1) Find middle point mid = (l + h)/2
2) If key is present at middle point, return mid.
3) Else If arr[l..mid] is sorted
    a) If key to be searched lies in range from arr[l]
       to arr[mid], recur for arr[l..mid].
    b) Else recur for arr[mid+1..h]
4) Else (arr[mid+1..h] must be sorted)
    a) If key to be searched lies in range from arr[mid+1]
       to arr[h], recur for arr[mid+1..h].
    b) Else recur for arr[l..mid] 

下面是上述想法的实现:

C++

// Search an element in sorted and rotated
// array using single pass of Binary Search
#include 
using namespace std;
 
// Returns index of key in arr[l..h] if
// key is present, otherwise returns -1
int search(int arr[], int l, int h, int key)
{
    if (l > h)
        return -1;
 
    int mid = (l + h) / 2;
    if (arr[mid] == key)
        return mid;
 
    /* If arr[l...mid] is sorted */
    if (arr[l] <= arr[mid]) {
        /* As this subarray is sorted, we can quickly
        check if key lies in half or other half */
        if (key >= arr[l] && key <= arr[mid])
            return search(arr, l, mid - 1, key);
        /*If key not lies in first half subarray,
           Divide other half  into two subarrays,
           such that we can quickly check if key lies
           in other half */
        return search(arr, mid + 1, h, key);
    }
 
    /* If arr[l..mid] first subarray is not sorted, then arr[mid... h]
    must be sorted subarray */
    if (key >= arr[mid] && key <= arr[h])
        return search(arr, mid + 1, h, key);
 
    return search(arr, l, mid - 1, key);
}
 
// Driver program
int main()
{
    int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int key = 6;
    int i = search(arr, 0, n - 1, key);
 
    if (i != -1)
        cout << "Index: " << i << endl;
    else
        cout << "Key not found";
}

Java

/* Java program to search an element in
   sorted and rotated array using
   single pass of Binary Search*/
 
class Main {
    // Returns index of key in arr[l..h]
    // if key is present, otherwise returns -1
    static int search(int arr[], int l, int h, int key)
    {
        if (l > h)
            return -1;
 
        int mid = (l + h) / 2;
        if (arr[mid] == key)
            return mid;
 
        /* If arr[l...mid] first subarray is sorted */
        if (arr[l] <= arr[mid]) {
            /* As this subarray is sorted, we
               can quickly check if key lies in
               half or other half */
            if (key >= arr[l] && key <= arr[mid])
                return search(arr, l, mid - 1, key);
            /*If key not lies in first half subarray,
           Divide other half  into two subarrays,
           such that we can quickly check if key lies
           in other half */
            return search(arr, mid + 1, h, key);
        }
 
        /* If arr[l..mid] first subarray is not sorted,
           then arr[mid... h] must be sorted subarry*/
        if (key >= arr[mid] && key <= arr[h])
            return search(arr, mid + 1, h, key);
 
        return search(arr, l, mid - 1, key);
    }
 
    // main function
    public static void main(String args[])
    {
        int arr[] = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
        int n = arr.length;
        int key = 6;
        int i = search(arr, 0, n - 1, key);
        if (i != -1)
            System.out.println("Index: " + i);
        else
            System.out.println("Key not found");
    }
}

Python3

# Search an element in sorted and rotated array using
# single pass of Binary Search
 
# Returns index of key in arr[l..h] if key is present,
# otherwise returns -1
def search (arr, l, h, key):
    if l > h:
        return -1
     
    mid = (l + h) // 2
    if arr[mid] == key:
        return mid
 
    # If arr[l...mid] is sorted
    if arr[l] <= arr[mid]:
 
        # As this subarray is sorted, we can quickly
        # check if key lies in half or other half
        if key >= arr[l] and key <= arr[mid]:
            return search(arr, l, mid-1, key)
        return search(arr, mid + 1, h, key)
 
    # If arr[l..mid] is not sorted, then arr[mid... r]
    # must be sorted
    if key >= arr[mid] and key <= arr[h]:
        return search(a, mid + 1, h, key)
    return search(arr, l, mid-1, key)
 
# Driver program
arr = [4, 5, 6, 7, 8, 9, 1, 2, 3]
key = 6
i = search(arr, 0, len(arr)-1, key)
if i != -1:
    print ("Index: % d"% i)
else:
    print ("Key not found")
 
# This code is contributed by Shreyanshi Arun

C#

/* C# program to search an element in
sorted and rotated array using
single pass of Binary Search*/
using System;
 
class GFG {
 
    // Returns index of key in arr[l..h]
    // if key is present, otherwise
    // returns -1
    static int search(int[] arr, int l, int h,
                      int key)
    {
        if (l > h)
            return -1;
 
        int mid = (l + h) / 2;
 
        if (arr[mid] == key)
            return mid;
 
        /* If arr[l...mid] is sorted */
        if (arr[l] <= arr[mid]) {
 
            /* As this subarray is sorted, we
            can quickly check if key lies in
            half or other half */
            if (key >= arr[l] && key <= arr[mid])
                return search(arr, l, mid - 1, key);
 
            return search(arr, mid + 1, h, key);
        }
 
        /* If arr[l..mid] is not sorted,
        then arr[mid... r] must be sorted*/
        if (key >= arr[mid] && key <= arr[h])
            return search(arr, mid + 1, h, key);
 
        return search(arr, l, mid - 1, key);
    }
 
    // main function
    public static void Main()
    {
        int[] arr = { 4, 5, 6, 7, 8, 9, 1, 2, 3 };
        int n = arr.Length;
        int key = 6;
        int i = search(arr, 0, n - 1, key);
 
        if (i != -1)
            Console.WriteLine("Index: " + i);
        else
            Console.WriteLine("Key not found");
    }
}
 
// This code is contributed by anuj_67.

的PHP

 $h) return -1;
 
    $mid = ($l + $h) / 2;
    if ($arr[$mid] == $key)
        return $mid;
 
    /* If arr[l...mid] is sorted */
    if ($arr[$l] <= $arr[$mid])
    {
         
        /* As this subarray is
           sorted, we can quickly
           check if key lies in
           half or other half */
        if ($key >= $arr[$l] &&
            $key <= $arr[$mid])
                return search($arr, $l,
                       $mid - 1, $key);
 
        return search($arr, $mid + 1,
                           $h, $key);
    }
 
    /* If arr[l..mid] is not
       sorted, then arr[mid... r]
       must be sorted*/
    if ($key >= $arr[$mid] &&
          $key <= $arr[$h])
        return search($arr, $mid + 1,
                            $h, $key);
 
    return search($arr, $l,
             $mid-1, $key);
}
 
    // Driver Code
    $arr = array(4, 5, 6, 7, 8, 9, 1, 2, 3);
    $n = sizeof($arr);
    $key = 6;
    $i = search($arr, 0, $n-1, $key);
 
    if ($i != -1)
        echo "Index: ", floor($i), " \n";
    else
        echo "Key not found";
 
// This code is contributed by ajit
?>

Java脚本


输出:

Index: 2

复杂度分析:

  • 时间复杂度: O(log n)。
    二进制搜索需要log n比较才能找到元素。因此,时间复杂度为O(log n)。
  • 空间复杂度: O(1)。
    由于不需要额外的空间。

感谢Gaurav Ahirwar提出上述解决方案。
如何处理重复项?
在所有允许重复的情况下,似乎都不可能在O(Logn)时间中进行搜索。例如,考虑在{2,2,2,2,2,2,2,2,2,0,2}和{2,0,2,2,2,2,2,2,2,2,2,2中搜索0 ,2}。
通过在中间进行恒定数量的比较,似乎无法决定是左半边还是右半边重复出现。

类似文章:

  • 在经过排序和旋转的数组中找到最小的元素
  • 给定一个经过排序和旋转的数组,请查找是否存在一对具有给定总和的数组。