...

/

Solution: Find the Peak Element

Solution: Find the Peak Element

Review various solution approaches to find the peak element in detail.

Solution 1

One simple way to solve this problem is the following:

using System;
class Program
{
/// <summary>
/// Finds a peak element in a array of integers.
/// </summary>
/// <param name="arr">Array of integers.</param>
/// <returns>A peak element in the given array.</returns>
public static int FindPeak(int[] arr)
{
// If the array is empty
if (arr.Length == 0)
{
return -1;
}
// If the array has only one element
if (arr.Length == 1)
{
return arr[0];
}
for (int i = 1; i < arr.Length - 1; i++)
{
if (arr[i] >= arr[i - 1] && arr[i] >= arr[i + 1])
{
return arr[i];
}
}
if (arr[0] >= arr[1])
{
return arr[0];
}
else if (arr[arr.Length - 1] >= arr[arr.Length - 2])
{
return arr[arr.Length - 1];
}
return -1;
}
// Driver code to test the above method
public static void Main(string[] args)
{
// Example 1
int[] arr1 = { 7, 11, 22, 13, 4, 0 };
Console.WriteLine("One peak point is: " + FindPeak(arr1));
// Example 2
int[] arr2 = { 0, 3, 100, 2, -1, 0 };
Console.WriteLine("One peak point is: " + FindPeak(arr2));
// Example 3
int[] arr3 = { 6, 5, 4, 3, 2, 1 };
Console.WriteLine("One peak point is: " + FindPeak(arr3));
}
}

Explanation

  1. We start from the beginning and compare each element with its neighbors.
  2. We return the peak element wherever we find it in the array.

If the array is sorted in an increasing order with no repetition, then the last element is always a peak element:

Press + to interact

In this case, the peak element is at the end of the array.

Time complexity

This solution gives us a worst-case time complexity of O(n)O(n).

Solution 2: This one’s more efficient

Using divide and conquer, we can speed up the whole process. Have a look at the solution given below:

using System;
class Program
{
/// <summary>
/// Finds a peak element in a array of integers within a specified range.
/// </summary>
/// <param name="low">Starting index of the array.</param>
/// <param name="high">Ending index of the array.</param>
/// <param name="arr">Array of integers.</param>
/// <returns>A peak element in the given array within the specified range.</returns>
public static int FindPeakRecursive(int low, int high, int[] arr)
{
// Finding the middle index
int middle = low + (high - low) / 2;
// If middle element is a peak
if ((middle == arr.Length - 1 || arr[middle + 1] <= arr[middle]) &&
(middle == 0 || arr[middle - 1] <= arr[middle]))
{
return middle;
}
// If left neighbor is greater, then peak is in the left half
if (middle > 0 && arr[middle - 1] > arr[middle])
{
return FindPeakRecursive(low, middle - 1, arr);
}
// If right neighbor is greater, then peak is in the right half
return FindPeakRecursive(middle + 1, high, arr);
}
/// <summary>
/// Finds a peak element in a array of integers.
/// </summary>
/// <param name="arr">Array of integers.</param>
/// <returns>A peak element in the given array.</returns>
public static int FindPeak(int[] arr)
{
return arr[FindPeakRecursive(0, arr.Length - 1, arr)];
}
// Driver code to test the above method
public static void Main(string[] args)
{
// Example 1
int[] arr1 = { 7, 11, 22, 13, 4, 0 };
Console.WriteLine("One peak point is: " + FindPeak(arr1));
// Example 2
int[] arr2 = { 0, 3, 100, 2, -1, 0 };
Console.WriteLine("One peak point is: " + FindPeak(arr2));
// Example 3
int[] arr3 = { 6, 5, 4, 3, 2, 1 };
Console.WriteLine("One peak point is: " + FindPeak(arr3));
}
}

Explanation

  • We start with the middle element of the array (line 15).
  • We compare the element with its neighbors.
    • If the middle element is not smaller than any of its neighbors, we return it (line 18).
    • If the middle element is smaller than its left neighbor, there is always a peak in the left half (line 25).
    • If the middle element is smaller than its right neighbor, there is always
...