Below is my solution for the leetcode 154: Find minimum in rotated
sorted array problem
Intuition#
Fact is, that you cannot solve this question in O(log n) time. The reason is because of duplicates.
Consider a situation like:
$$
[2,2,2,2,1,2,2]
$$
where mid is at 3 and the minium number here is clearly $$1$$. But our binary search algorithm will not be able to figure out in which direction it should go, since starting, ending and middle values are all same. In this case the best we can do is increment mid which makes the worst running time: O(n)
However, it is possible to solve this problem in O(n/2) as explain below.
Approach#
We will make use of the fact that a sorted array follows the (min) heap property i.e. in a sorted array, at all parent nodes are smaller than their children.
And if this sorted array is rotated, then the place at which the first violation occurs is the subtree where the answer will be found.
Complexity#
- Time complexity: $$O(n/2)$$
- Space complexity: $$O(1)$$
Code#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| var findMin = function(a) {
/**
Approach:
You cannot solve this problem in O(log n) since it contains duplicate
values. But you can actually solve this problem in O(n/2) by using the
fact that a sorted array follows heap property. And if a sorted array is
rotated then the heap property no longer holds. to find the minium
element traverse the array, and find the first subtree where the heap
property does not hold. the minium of the 2 values where the heap
property does not satisfy is also minium in the array.
Time: O(n/2)
Space: O(1)
*/
let A = a.length;
let i = 0;
while ( i <= Math.floor(A/2)-1 ) {
let root = i;
let lc = 2*i + 1;
let rc = 2*i + 2;
let smallest = root;
if ( lc < A && a[lc] < a[smallest] ) smallest = lc;
if ( rc < A && a[rc] < a[smallest] ) smallest = rc;
if ( smallest != root )
/* violation found. the value at smallest is minium */
return a[smallest];
i++;
}
/* no violation found. Either the array is sorted ar there
it is all duplicates, in either case, return the first
element.
*/
return a[0];
};
|