Find Trough/Peak Element
Find Peak Element (LC.162)
Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. You may imagine that num[-1] = num[n] = -∞.
Example
Input: [1, 2, 3, 1]
Return: A[2] = 3, return 2
Input: [1, 2, 1, 3, 4, 5, 7, 6]
Return: A[1] = 2 or A[6] = 7, return 1 or 6
Analysis
This is more fun to do. This is no longer a vanilla binary search. This is decrease and conquer. We need to exploit the sorted property and somehow pick half of the original problem to solve. We have 4 cases: 1. mid is peak, then A[mid-1] < A[mid] < A[mid+1] 2. if the seq is increasing, then search right 3. if the seq is decreasing, then search left 4. else mid is a trough, either left or right is fine
Code
public int findPeakElement(int[] nums) {
if (nums == null || nums.length == 0) {
return -1;
}
return peakHelper(nums, 0, nums.length - 1);
}
private int peakHelper(int[] nums, int start, int end) {
// base case 2 elements (make sure no array out of bound exception)
if (start + 1 >= end) {
if (nums[start] > nums[end]) {
return start;
} else {
return end;
}
}
// decrease
int mid = start + (end - start) / 2;
// conquer
if (nums[mid - 1] < nums[mid] && nums[mid] > nums[mid + 1]) {
// nums[mid] is a peak
return mid;
} else if (nums[mid - 1] < nums[mid] && nums[mid] < nums[mid + 1]) {
// in an increasing seq, search right
return peakHelper(nums, mid + 1, end);
} else if (nums[mid - 1] > nums[mid] && nums[mid] > nums[mid + 1]) {
// in a decreasing sq, search left
return peakHelper(nums, start, mid - 1);
} else {
// a trough, either left or right
return peakHelper(nums, start, mid - 1);
}
}
The comparisons can be further simplified. But since we have a clear understanding and a working code, objectives accomplished.
Maximum Number in Mountain Sequence
Given a mountain sequence of n integers which increase firstly and then decrease, find the mountain top.
Example
Given nums = [1, 2, 4, 8, 6, 3] return 8
Given nums = [10, 9, 8, 7], return 10
Analysis
Same thing as above. Let's try while loop this time.
Code
public int mountainSequence(int[] nums) {
if (nums == null || nums.length == 0)
return -1;
int start = 0, mid, end = nums.length - 1;
// guarantee more than 2 elements
while (start + 1 < end) {
mid = (start + end) / 2;
if (nums[mid - 1] < nums[mid] && nums[mid] > nums[mid + 1]) {
// a peak
return nums[mid];
} else if (nums[mid - 1] < nums[mid] && nums[mid] < nums[mid + 1]) {
// increasing seq, search right
start = mid + 1;
} else {
// decreasing seq, or a trough, search left
end = mid - 1;
}
}
// base case
if (nums[start] > nums[end]) {
return nums[start];
} else {
return nums[end];
}
}
Find Peak Element II
Find peak in a 2D array.
Reference
Find Peak Element by segmentfault
Last updated