Given a Sorted Array which can be rotated find an Element in it in minimum Time Complexity.
eg : Array contents can be [8, 1, 2, 3, 4, 5]. Assume you search 8 in it.
The idea is to find the pivot point, divide the array into two sub-arrays and perform a binary search. For a sorted (in increasing order) and rotated array, the pivot element is the only element for which the next element to it is smaller than it. Using binary search based on the above idea, pivot can be found.
var search = function(nums, target) { if(nums. length == 0 || nums == null) return -1; let left = 0; let right = nums. length-1; while(left < right){ let mid = Math. floor((left+right)/2); if(nums[mid]>nums[right]){ left = mid+1; }else{ right = mid; } } let pivot = left; left = 0; right = nums.
You can use binary search on the rotated array (with some modifications). Let N be the number you are searching for: Read the first number (arr[start]) and the number in the middle of the array (arr[end]):
The solution still works out to a binary search in the sense that you'll need to partition the array into two parts to be examined.
In a sorted array, you just look at each part and determine whether the element lives in the first part (let's call this A) or the second part (B). Since, by the definition of a sorted array, partitions A and B will be sorted, this requires no more than some simple comparisons of the partition bounds and your search key.
In a rotated sorted array, only one of A and B can be guaranteed to be sorted. If the element lies within a part which is sorted, then the solution is simple: just perform the search as if you were doing a normal binary search. If, however, you must search an unsorted part, then just recursively call your search function on the non-sorted part.
This ends up giving on a time complexity of O(lg n)
.
(Realistically, I would think that such a data structure would have a index accompanying it to indicate how many positions the array has been rotated.)
Edit: A search on Google takes me to this somewhat dated (but correct) topic on CodeGuru discussing the same problem. To add to my answer, I will copy some pseudocode that was given there so that it appears here with my solution (the thinking follows the same lines):
Search(set): if size of set is 1 and set[0] == item return info on set[0] divide the set into parts A and B if A is sorted and the item is in the A's range return Search(A) if B is sorted and the item is in the B's range return Search(B) if A is not sorted return Search(A) if B is not sorted return Search(B) return "not found"
O(log(N))
Reduced to the problem of finding the largest number position, which can be done by checking the first and last and middle number of the area, recursively reduce the area, divide and conquer, This is O(log(N)) no larger than the binary search O(log(N)).
EDIT: For example, you have
6 7 8 1 2 3 4 5 ^ ^ ^
By looking at the 3 numbers you know the location of the smallest/largest numbers (will be called mark later on) is in the area of 6 7 8 1 2, so 3 4 5 is out of consideration (usually done by moving your area start/end index(int) pointing to the number 6 and 2 ).
Next step,
6 7 8 1 2 ^ ^ ^
Once again you will get enough information to tell which side (left or right) the mark is, then the area is reduced to half again (to 6 7 8).
This is the idea: I think you can refine a better version of this, actually, for an interview, an OK algorithm with a clean piece of codes are better than the best algorithm with OK codes: you 'd better hand-on some to heat-up.
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With