Це можна зробити за 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
тег. Це заохочувало б людей лагідно підштовхувати вас у правильному напрямку, замість того, щоб розміщувати відповіді, що відповідають умовам.