For an array a: a1, a2, … ak, … an, ak is a peak if and only if ak-1 ≤ ak ≥ ak+1 when 1 < k and k < n. a1 is a peak if a1 ≥ a2, and an is a peak if an-1 ≤ an. The goal is to find one peak from the array.
A divide and conquer algorithm is given as follows:
find_peak(a,low,high):
mid = (low+high)/2
if a[mid-1] <= a[mid] >= a[mid+1] return mid // this is a peak;
if a[mid] < a[mid-1]
return find_peak(a,low,mid-1) // a peak must exist in A[low..mid-1]
if a[mid] < a[mid+1]
return find_peak(a,mid+1,high) // a peak must exist in A[mid+1..high]
Why this algorithm is correct? I think it may suffer from losing half of the array in which a peak exists.
The algorithm is correct, although it requires a bit of calculus to prove. First case is trivial → peak. Second case is a "half peak", meaning that it has the down slope, but not up.
We have 2 possibilities here:
- The function is monotonically decreasing till amid → a1 ≥ a2 is the peak.
- The function is not monotonically decreasing till amid → There is a 1≥k≥mid, for which ak ≥ ak-1. Let's choose the largest k for which this statement is true → ak+1 < ak ≥ ak-1 → and that's the peak.
Similar argument can be applied for the third case with the opposite "half peak".
来源:https://stackoverflow.com/questions/16887279/divide-and-conquer-algorithm-applied-in-finding-a-peak-in-an-array