Это можно сделать 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
if(low > high)
return -1
if(arr[mid] == key)
return mid
if(arr[low] <= arr[mid])
if (arr[low] <= key && arr[mid] >= key)
return search(arr,key,low,mid-1)
else
return search(arr,key,mid+1,high)
end-if
else
if(arr[mid] <= key && arr[high] >= key)
return search(arr,key,mid+1,high)
else
return search(arr,key,low,mid-1)
end-if
end-if
end-function
Ключевым моментом здесь является то, что всегда будет отсортирован один подмассив, с помощью которого мы можем отбросить половину массива.
homework
тег. Это побудит людей мягко подтолкнуть вас в правильном направлении вместо того, чтобы публиковать простые ответы.