Title : Searching in Flip Order
Difficulty : Medium
Topic content :
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,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.
Your algorithm's runtime complexity must be in the order of O(log n).
Translation :
Suppose an array sorted in ascending order is flipped without knowing the rotation point in advance.
(ie. 0,1,2,4,5,6,7 could become 4,5,6,7,0,1,2).
You get the target value for your search. Returns -1 if its index is not found in the array.
There are no duplicates in the array.
The runtime complexity of your algorithm should be O(log n)
My idea : the complexity is O(log n), but the array is only basically ordered, and the best case of the sorting algorithm is also O(N). This weak chicken can't think of a good way. . .
Then force it, first insert a wave of sorting, and then search by dichotomy.
However, in the end, the subscript needs to be returned, and the subscript will change after sorting, so a new array is created to store the subscript. During the sorting process, the corresponding value of this array moves together.
MyCode:
1 public int search(int[] nums, int target) { 2 int[] index = new int[nums.length]; 3 for (int i = 0; i < nums.length; i++) { 4 index[i] = i; 5 } 6 insertSort(nums, index); 7 return binaryFind(nums, target, index); 8 } 9 10 static int binaryFind(int[] nums, int target, int[] index) { 11 int low = 0; 12 int high = nums.length - 1; 13 while (low <= high) { 14 int mid = low + (high - low)/2; 15 if (nums[mid] == target) { 16 return index[mid]; 17 } else if (nums[mid] > target) { 18 high = mid - 1; 19 } else { 20 low = mid + 1; 21 } 22 } 23 return -1; 24 } 25 26 static void insertSort(int[] nums, int[] index) { 27 for (int i = 1; i < nums.length; i++) { 28 int temp = nums[i]; 29 int temp2 = index[i]; 30 int j = i - 1; 31 while (j > -1 && nums[j] > temp) { 32 nums[j+1] = nums[j]; 33 index[j+1] = index[j]; 34 j--; 35 } 36 nums[j+1] = temp; 37 index[j+1] = temp2; 38 } 39 }
My algorithm complexity : O(N 2 ), because the worst case for insertion sort is O(N 2 ).
Problems during encoding :
1. Forget the logic of insertion sort. .
Answer code :
1 public int search(int[] A, int target) { 2 int n = A.length; 3 int lo=0,hi=n-1; 4 while(lo<hi){ 5 int mid=(lo+hi)/2; 6 if(A[mid]>A[hi]) lo=mid+1; 7 else hi=mid; 8 } 9 int rot=lo; 10 lo=0;hi=n-1; 11 while(lo<=hi){ 12 int mid=(lo+hi)/2; 13 int realmid=(mid+rot)%n; 14 if(A[realmid]==target)return realmid; 15 if(A[realmid]<target)lo=mid+1; 16 else hi=mid-1; 17 } 18 return -1; 19 }
Answer complexity: O(logN)
Answer idea: First, use the characteristics of the local order of the array and the condition of A[mid]>A[hi] to locate the subscript of the smallest value by dichotomy. Note that when A[mid]<=A[ When hi] , it should be hi=mid, because the mid at this time may be the smallest point, so it cannot be ignored. [ When the required point is not the directly positioned mid (waiting for the end of the loop), mid may be the final value, and the values of lo and hi in the next layer cannot both exclude mid, one of which is mid ]
After finding the minimum point, record it, and then continue to perform a binary search on the original array. However, the mid involved in the comparison should be changed to realMid=(mid+rot)%n
by[4,5,6,7,0,1,2]为例,找到最小值(真起点)0的下标4后,取mid=(0+6)/2 = 3,而真正的中点下标应该等于(mid+rot)%n = (3+4)%7 = 0
The subsequent movement to the left and right is the same, so the value of mid can still be changed.