Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,0 1 2 4 5 6 7might become4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
Complexity: O(logN) time, O(logN) space
The Idea: Use binary search to find index of pivot, which we can identify as the minimum element in the array. In other words, the target value will have a unique position where both its left and right neighbors are the same or larger. Then use binary search to search left or right of pivot.
// no need to exit condition because we are guarentee to// linearly converge to a pivot point (check is made that it exists)intfind_pivot(vector<int> &nums,int low,int high) {int mid = low + ((high - low) /2);if (nums.at(mid) >nums.at(mid +1)) {return mid +1; }elseif (nums.at(low) <=nums.at(mid)) returnfind_pivot(nums, mid +1, high);elsereturnfind_pivot(nums, low, mid -1);}intbinary_search(vector<int> &nums,int low,int high,int target) {if (high < low) return-1;int mid = low + ((high - low) /2);if (nums.at(mid) == target) return mid;elseif (nums.at(mid) > target) returnbinary_search(nums, low, mid -1, target);elsereturnbinary_search(nums, mid +1, high, target);}intsearch(vector<int>& nums,int target) {if (nums.empty()) return-1;int start =0;int end =nums.size() -1; // not rotatedif (nums.front() <=nums.back()) returnbinary_search(nums, start, end, target); // find pivot pointint pivot_i =find_pivot(nums, start, end);if (nums.at(pivot_i) == target)return pivot_i; // search right [pivot, end]elseif (target >=nums.at(pivot_i) && target <=nums.back())returnbinary_search(nums, pivot_i +1, end, target); // search left [start, pivot]elsereturnbinary_search(nums, start, pivot_i -1, target);}
Testing
intmain(){ // t1 vector<int> nums1 = { 1 };assert(search(nums1,1) ==0);assert(search(nums1,-1) ==-1); // t2 vector<int> nums2 = { 4,5,6,7,0,1,2 };for (int i =0; i <nums2.size(); i++) assert(search(nums2,nums2.at(i)) == i);assert(search(nums2,10) ==-1); // t3 vector<int> nums3 = { 4,5,1,2,3 };for (int i =0; i <nums3.size(); i++)assert(search(nums3,nums3.at(i)) == i);}