class Solution:
    def findPeakElement(self, nums):
        left, right = 0, len(nums) - 1
        while left < right:
            mid = (left + right) // 2
            if nums[mid] < nums[mid + 1]:
                left = mid + 1
            else:
                right = mid
        return left
      class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < nums[mid + 1])
                left = mid + 1;
            else
                right = mid;
        }
        return left;
    }
};
      class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0, right = nums.length - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < nums[mid + 1])
                left = mid + 1;
            else
                right = mid;
        }
        return left;
    }
}
      var findPeakElement = function(nums) {
    let left = 0, right = nums.length - 1;
    while (left < right) {
        let mid = Math.floor((left + right) / 2);
        if (nums[mid] < nums[mid + 1]) {
            left = mid + 1;
        } else {
            right = mid;
        }
    }
    return left;
};
      
    Given an array of integers nums, find a peak element and return its index. A peak element is an element that is strictly greater than its neighbors.
  
nums[-1] = -∞ and nums[n] = -∞ where n is the length of the array.
    Your task is to return the index of any peak element in nums.
  
The simplest way to solve this problem is to scan through the array and check for each element if it is greater than its neighbors. This is the brute-force approach, but it is not efficient for large arrays.
However, the problem hints at a more efficient solution. Since we only need any peak and not all of them, and since the array can be unsorted, we can use a modified binary search to find a peak in logarithmic time. The key is to compare the middle element with its neighbors and decide which direction to search next.
This is similar to climbing a mountain: if you're standing at a point and the next point is higher, you keep moving in that direction until you reach a peak.
left and right, at the start and end of the array.
    left < right:
      mid = (left + right) // 2 (or language equivalent).nums[mid] and nums[mid + 1]:nums[mid] < nums[mid + 1], it means there is a peak to the right, so move left to mid + 1.mid or to the left, so move right to mid.left == right, this index is a peak, so return left.
    
    This approach works because if you're on a slope (i.e., nums[mid] < nums[mid + 1]), a peak must exist in that direction. If you're on a "downhill" or "plateau", a peak could be at mid or in the other direction.
  
    Consider the input nums = [1, 2, 1, 3, 5, 6, 4].
  
left = 0, right = 6, mid = 3 (nums[3]=3).nums[3]=3 and nums[4]=5. Since 3 < 5, move left to mid + 1 = 4.left = 4, right = 6, mid = 5 (nums[5]=6).nums[5]=6 and nums[6]=4. Since 6 > 4, move right to mid = 5.left = 4, right = 5, mid = 4 (nums[4]=5).nums[4]=5 and nums[5]=6. Since 5 < 6, move left to mid + 1 = 5.left = right = 5. Return 5 as the index of a peak element (nums[5]=6).The process finds a peak efficiently, without checking every element.
nums, because we may need to check each element. Space is O(1).
    The binary search is possible because, regardless of the array's order, there is always a peak in any subarray, and the search always moves toward one.
The "Find Peak Element" problem can be solved efficiently by leveraging a binary search approach. By always moving towards a neighbor that is larger, we guarantee finding a peak in logarithmic time. The key insight is that, due to the definition of a peak and the boundary conditions, a peak always exists, and we do not need to check every element. This makes the solution both elegant and highly efficient.