I cannot refute the work of this solution, so I would be happy if someone could.
Consider an array 'a' indexed from 1 to n.
low = 1 high = n mid = (low + high)/2
Without losing too much generality, I'm going to assume that the values โโof the array are different. So, in the middle, a [mid-1], [mid], [mid + 1] can be similar:
Case 1: /\ Case 2: \/ Case 3: / / Case 4: \ \ Case 5(boundary): / Case 6(boundary): \
& m = mid
Each case can be verified using the following conditions:
1: a[m] > a[m-1] && a[m] > a[m+1] 2: a[m] < a[m-1] && a[m] < a[m+1] 3: a[m] > a[m-1] && a[m] < a[m+1] 4: a[m] < a[m-1] && a[m] > a[m+1]
I will also ignore the explanation of the boundary cases:
The second case is the desired case when a [m] are local minima
for the third case:
there are always local minima on the left, therefore, set h = m - 1 and continue
for the 4th case:
there are always local minima on the right, therefore l = m + 1 and continue
for the 1st case, I can go in any direction: I believe that this works, because the only time you reduce the segment that you are considering is when you are sure that there are local lows in the reduced segment, so in the segment you are looking for will always have local lows.
Note. This will only work for finding single local minimums, not for each local minimum. For the latter case, O (n) is required, since you definitely need to see the entire array at least once.