给定一个经过排序和旋转的数组arr [] ,任务是在O(log n)时间中在旋转的数组中找到一个元素(重复)。
注意:在键存在的地方打印索引。如果有多个答案,请打印其中的任何一个
例子:
Input: arr[] = {3, 3, 3, 1, 2, 3}, key = 3
Output: 0
arr[0] = 3
Input: arr[] = {3, 3, 3, 1, 2, 3}, key = 11
Output: -1
11 is not present in the given array.
方法:这个想法与先前的想法相同,没有重复。唯一的区别是,由于存在重复项,所以arr [low] == arr [mid]是可能的,前半部分可能是乱序的(即不是按升序排列,例如{3,1,2, 3,3,3,3}),我们必须分别处理此案。
在这种情况下,可以保证arr [high]也等于arr [mid] ,因此可以在原始逻辑之前检查条件arr [mid] == arr [low] == arr [high]然后向左和向右都向中间移动1并重复。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the index of the
// key in arr[l..h] if the key is present
// otherwise return -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;
// The tricky case, just update left and right
if ((arr[l] == arr[mid])
&& (arr[h] == arr[mid]))
{
++l;
--h;
return search(arr, l, h, key);
}
// If arr[l...mid] is sorted
if (arr[l] <= arr[mid]) {
// As this subarray is sorted, we can quickly
// check if key lies in any of the halves
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
// If key does not lie in the first half
// subarray then divide the other half
// into two subarrays such that we can
// quickly check if key lies in the 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 code
int main()
{
int arr[] = { 3, 3, 1, 2, 3, 3 };
int n = sizeof(arr) / sizeof(int);
int key = 3;
cout << search(arr, 0, n - 1, key);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the index of the
// key in arr[l..h] if the key is present
// otherwise return -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;
// The tricky case, just update left and right
if ((arr[l] == arr[mid])
&& (arr[h] == arr[mid]))
{
l++;
h--;
return search(arr,l,h,key);
}
// If arr[l...mid] is sorted
else if (arr[l] <= arr[mid])
{
// As this subarray is sorted, we can quickly
// check if key lies in any of the halves
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
// If key does not lie in the first half
// subarray then divide the other half
// into two subarrays such that we can
// quickly check if key lies in the other half
else
return search(arr, mid + 1, h, key);
}
// If arr[l..mid] first subarray is not sorted
// then arr[mid... h] must be sorted subarray
else if (key >= arr[mid] && key <= arr[h])
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
}
// Driver code
public static void main (String[] args)
{
int arr[] ={3, 3, 1, 2, 3, 3};
int n = arr.length;
int key = 3;
System.out.println(search(arr, 0, n - 1, key));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach
# Function to return the index of the
# key in arr[l..h] if the key is present
# otherwise return -1
def search(arr, l, h, key) :
if (l > h) :
return -1;
mid = (l + h) // 2;
if (arr[mid] == key) :
return mid;
# The tricky case, just update left and right
if ((arr[l] == arr[mid]) and (arr[h] == arr[mid])) :
l += 1;
h -= 1;
return search(arr, l, h, key)
# If arr[l...mid] is sorted
if (arr[l] <= arr[mid]) :
# As this subarray is sorted, we can quickly
# check if key lies in any of the halves
if (key >= arr[l] and key <= arr[mid]) :
return search(arr, l, mid - 1, key);
# If key does not lie in the first half
# subarray then divide the other half
# into two subarrays such that we can
# quickly check if key lies in the 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] and key <= arr[h]) :
return search(arr, mid + 1, h, key);
return search(arr, l, mid - 1, key);
# Driver code
if __name__ == "__main__" :
arr = [ 3, 3, 1, 2, 3, 3 ];
n = len(arr);
key = 3;
print(search(arr, 0, n - 1, key));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the index of the
// key in arr[l..h] if the key is present
// otherwise return -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;
// The tricky case, just update left and right
if ((arr[l] == arr[mid])
&& (arr[h] == arr[mid]))
{
++l;
--h;
return search(arr, l, h, key)
}
// If arr[l...mid] is sorted
if (arr[l] <= arr[mid])
{
// As this subarray is sorted, we can quickly
// check if key lies in any of the halves
if (key >= arr[l] && key <= arr[mid])
return search(arr, l, mid - 1, key);
// If key does not lie in the first half
// subarray then divide the other half
// into two subarrays such that we can
// quickly check if key lies in the 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 code
public static void Main ()
{
int []arr = { 3, 3, 1, 2, 3, 3 };
int n = arr.Length;
int key = 3;
Console.WriteLine(search(arr, 0, n - 1, key));
}
}
// This code is contributed by AnkitRai01
输出
4