Solution: Peak Element
This review discusses the solution of the Peak Element Challenge in detail.
We'll cover the following...
Solution #1
One simple way to solve this problem is:
class PeakElement {public static int findPeak(int[] array) {//calculating array lengthint len = array.length;if (len == 0) {return -1;}if (len == 1) {return array[0];}if (array[0] >= array[1]) {return array[0];}//traversing arrayfor (int i = 1; i < len - 1; i++) {//if current value is greater than previous and the next value return itif ((array[i] >= array[i - 1]) & (array[i] >= array[i + 1])) {return array[i];}}if (array[len - 1] >= array[len - 2]) {return array[len - 1];}return -1;}/* Driver program to test above functions */public static void main(String args[]) {int[] array = { 7, 11, 22, 13, 4, 0 };System.out.println("Peak element is: " + findPeak(array));int[] array1 = {0,3,100,2,-1,0};System.out.println("Peak element is: " + findPeak(array1));}}
In the code above, we:
- Start from the beginning and compare each element with its neighbors.
- Return the peak element wherever it is found in the array.
There must always be one peak element in an array with distinct elements but it’s possible that the array is sorted in ascending order just like this:
In this case, the peak element is at the end of the array.
Time complexity
The implementation of this solution is left for your own understanding. It gives us a worst-case time complexity of .
Can we do better?
"Solution #2: Divide and conquer (efficient)
Using divide and conquer, we can speed up the whole process. Have a look at the solution given below:
class PeakElement {// This function is based on the recursive binary search algorithm returning the index of the peak element in the given arraypublic static int findPeakRecursive(int low, int high, int size, int array[]) {// Just as in binary search, we will first find the middle elementint middle = low + (high - low) / 2;// If neighbors of the middle element exist, compare them with the elementif ((middle == size - 1 || array[middle + 1] <= array[middle]) &&(middle == 0 || array[middle - 1] <= array[middle]))return middle;// If the left neighbor of the middle element is greater, The peak element must be in the left subarrayelse if (array[middle - 1] > array[middle] && middle > 0)return findPeakRecursive(low, (middle - 1), size, array);// If the right neighbor of the middle element is greater, The peak element must be in the right subarrayelsereturn findPeakRecursive((middle + 1), high, size, array);}// Wrapper to call the recursive findPeakRecursive()public static int findPeak(int arr[]) {int n = arr.length;return findPeakRecursive(0, n - 1, n, arr);}/* Driver program to test above functions */public static void main(String args[]) {// A 2D array to store integer input arraysint[][] inputs = { {7, 11, 22, 13, 4, 0} , {13, 27, 54, 11, 99, 1} ,{0, 1, 2, 3, 4, 5} , {10, 9, 8, 7, 6}};int peak = 0; // variable to store the peak value for each input arrayfor (int i = 0; i < inputs.length; i++) {peak = findPeak(inputs[i]);if (i == 2)System.out.println("Input Array: " + Arrays.toString(inputs[i]) + " ----> Peak = \"" + inputs[i][peak] + "\"\t\t (Ascending Order - Peak = Last Element)\n");else if (i == 3)System.out.println("Input Array: " + Arrays.toString(inputs[i]) + " ----> Peak = \"" + inputs[i][peak] + "\"\t\t(Descending Order - Peak = First Element)\n");elseSystem.out.println("Input Array: " + Arrays.toString(inputs[i]) + " ----> Peak = \"" + inputs[i][peak] + "\"\n");}}}
Explanation
-
Line 37: The driver calls the
findPeak(int[]array)
function. -
Line 27: A helper function
findPeakRecursive(int high, int low, int size, int[]arr)
is called to get the peak value. -
Line 7: The function starts with calculating the middle index of the array.
-
...