ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Find Peak Element in Sorted Array

C++

Goal -- WPM

Ready
Exercise Algorithm Area
1#include <vector>
2#include <iostream>
3
4// Helper function to check if an element is a peak
5bool isPeak(const std::vector<int>& nums, int index) {
6int n = nums.size();
7if (index < 0 || index >= n) {
8return false; // Out of bounds is not a peak
9}
10// Check left neighbor
11bool greaterThanLeft = (index == 0) || (nums[index] > nums[index - 1]);
12// Check right neighbor
13bool greaterThanRight = (index == n - 1) || (nums[index] > nums[index + 1]);
14
15return greaterThanLeft && greaterThanRight;
16}
17
18// Function to find a peak element in an array
19// A peak element is an element that is strictly greater than its neighbors.
20// The array may contain multiple peaks; in that case, return the index to any one of the peaks.
21// Assume nums[-1] = nums[n] = -infinity.
22int findPeakElement(const std::vector<int>& nums) {
23int n = nums.size();
24
25// Edge case: empty array
26if (n == 0) {
27return -1; // Or throw an exception, depending on requirements
28}
29
30// Edge case: single element array
31if (n == 1) {
32return 0;
33}
34
35int left = 0;
36int right = n - 1;
37
38// Binary search for a peak element
39while (left < right) {
40int mid = left + (right - left) / 2;
41
42// If mid element is greater than its right neighbor, then a peak must exist on the left side (including mid)
43if (nums[mid] > nums[mid + 1]) {
44right = mid;
45}
46// If mid element is less than its right neighbor, then a peak must exist on the right side (excluding mid)
47else {
48left = mid + 1;
49}
50}
51
52// At the end of the loop, 'left' will point to a peak element.
53// This is because the search space is always guaranteed to contain a peak.
54// If nums[mid] > nums[mid+1], a peak is in [left, mid].
55// If nums[mid] < nums[mid+1], a peak is in [mid+1, right].
56// The loop terminates when left == right, which must be a peak.
57return left;
58}
59
60int main() {
61std::vector<int> nums1 = {1, 2, 3, 1};
62std::cout << "Peak element index in {1, 2, 3, 1}: " << findPeakElement(nums1) << std::endl;
63
64std::vector<int> nums2 = {1, 2, 1, 3, 5, 6, 4};
65std::cout << "Peak element index in {1, 2, 1, 3, 5, 6, 4}: " << findPeakElement(nums2) << std::endl;
66
67std::vector<int> nums3 = {1};
68std::cout << "Peak element index in {1}: " << findPeakElement(nums3) << std::endl;
69
70std::vector<int> nums4 = {3, 2, 1};
71std::cout << "Peak element index in {3, 2, 1}: " << findPeakElement(nums4) << std::endl;
72
73std::vector<int> nums5 = {1, 2, 3};
74std::cout << "Peak element index in {1, 2, 3}: " << findPeakElement(nums5) << std::endl;
75
76return 0;
77}
Algorithm description viewbox

Find Peak Element in Sorted Array

Algorithm description:

This C++ code finds a peak element in an array where a peak is defined as an element strictly greater than its neighbors. The problem assumes that elements outside the array bounds are negative infinity. This is a common problem in competitive programming and algorithm analysis, often used to illustrate binary search on a non-monotonic property.

Algorithm explanation:

The `findPeakElement` function uses a modified binary search algorithm to efficiently locate a peak element. The core idea is that if `nums[mid] < nums[mid + 1]`, then a peak must exist in the right half (`mid + 1` to `right`) because the sequence is increasing at `mid`. Conversely, if `nums[mid] > nums[mid + 1]`, a peak must exist in the left half (`left` to `mid`) because the sequence is decreasing at `mid`. The loop invariant is that the range `[left, right]` always contains at least one peak. The time complexity is O(log n) due to the binary search, and the space complexity is O(1) as it only uses a few variables. Edge cases such as empty or single-element arrays are handled explicitly. The assumption of `nums[-1] = nums[n] = -infinity` simplifies boundary checks and guarantees a peak's existence.

Pseudocode:

function findPeakElement(nums):
  n = length of nums
  if n is 0:
    return -1
  if n is 1:
    return 0

  left = 0
  right = n - 1

  while left < right:
    mid = left + (right - left) / 2
    if nums[mid] > nums[mid + 1]:
      right = mid
    else:
      left = mid + 1

  return left