Question
from lintcode
There is an integer array which has the following features:
The numbers in adjacent positions are different.
A[0] < A[1] && A[A.length - 2] > A[A.length - 1].
We define a position P is a peak if:
A[P] > A[P-1] && A[P] > A[P+1]
Find a peak element in this array. Return the index of the peak.
Notice
It's guaranteed the array has at least one peak.
The array may contain multiple peeks, find any of them.
The array has at least 3 numbers in it.
Example
Given [1, 2, 1, 3, 4, 5, 7, 6]
Return index 1 (which is number 2) or 6 (which is number 7)
Idea
The key to reaching an optimal solution is to well-utilize the assumptions of the question. Since the question guarantees the following things:
The leftmost element and the rightmost element are both lower than their adjacent values, and no adjacent values will be the same. This means the integers must keep increasing from both ends to the middle point until encountering a Peak.
If you cut half of the array, you either
- get a peak
- get an element which is increasing to its left peak, then, go to cut 1/2 of the left segment
- get an element which is increasing to its right peak, then go to cut 1/2 of the right segment
Keep cutting half until you encounter the peak.
public class Solution {
/*
* @param A: An integers array.
* @return: return any of peek positions.
*/
public int findPeak(int[] A) {
// It is guranteed that A[0] < A[1] && A[A.length - 2] > A[A.length - 1]
int start = 1;
int end = A.length - 2;
while (start + 1 < end) {
int mid = (start + end) - 2;
if (A[mid - 1] < A[mid]) {
if (A[mid + 1] < A[mid])
return mid;
start = mid;
} else {
end = mid;
}
}
if (A[start] < A[end]) return end;
return start;
}
}
网友评论