Во-первых, вам нужно найти постоянную сдвига, k.
Это можно сделать за O (LGN) времени.
С помощью постоянного смещения k вы можете легко найти элемент, который вы ищете, используя
бинарный поиск с константой k. Расширенный бинарный поиск также занимает время O (lgN)
Общее время выполнения O (lgN + lgN) = O (lgN) * 1001 *
Чтобы найти постоянный сдвиг, k. Вам просто нужно найти минимальное значение в массиве. Индекс минимального значения массива говорит вам постоянное смещение.
Рассмотрим отсортированный массив
[1,2,3,4,5].
The possible shifts are:
[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;
}
Hope this helps!=)
Soon Chee Loong,
University of Toronto