1+ """
2+ # 162. Find Peak Element
3+
4+ ## Problem Statement
5+
6+ A peak element is an element that is **strictly greater than its neighbors**.
7+
8+ Given a 0-indexed integer array `nums`, find a peak element and return its index.
9+ If the array contains multiple peaks, return the index of **any** peak.
10+
11+ You may imagine that:
12+
13+ nums[-1] = nums[n] = -∞
14+
15+ This means the elements outside the array are considered negative infinity.
16+
17+ ### Example 1
18+ Input:
19+ nums = [1,2,3,1]
20+
21+ Output:
22+ 2
23+
24+ Explanation:
25+ nums[2] = 3 is greater than both neighbors.
26+
27+ ### Example 2
28+ Input:
29+ nums = [1,2,1,3,5,6,4]
30+
31+ Output:
32+ 5
33+
34+ Explanation:
35+ nums[5] = 6 is a peak element.
36+
37+ ---
38+
39+ ## Intuition
40+
41+ A linear scan can find a peak in O(n) time, but the problem asks for an
42+ algorithm with O(log n) complexity.
43+
44+ We can use **Binary Search** by observing the slope around the middle element.
45+
46+ Consider:
47+
48+ nums[mid] and nums[mid + 1]
49+
50+ ### Case 1:
51+ nums[mid] > nums[mid + 1]
52+
53+ This means we are on a descending slope.
54+
55+ Example:
56+ 1 3 5 4 2
57+
58+ mid
59+
60+ Since the sequence is decreasing after `mid`, a peak must exist on the
61+ left side (including `mid` itself).
62+
63+ Therefore:
64+ r = mid
65+
66+ ### Case 2:
67+ nums[mid] < nums[mid + 1]
68+
69+ This means we are on an ascending slope.
70+
71+ Example:
72+ 1 2 4 6 8
73+
74+ mid
75+
76+ Since the sequence is increasing, a peak must exist on the
77+ right side.
78+
79+ Therefore:
80+ l = mid + 1
81+
82+ By repeatedly reducing the search space, we eventually reach a single
83+ element which is guaranteed to be a peak.
84+
85+ ---
86+
87+ ## Approach
88+
89+ 1. Initialize:
90+ - l = 0
91+ - r = n - 1
92+
93+ 2. While l < r:
94+ - Find middle index.
95+ - Compare nums[mid] and nums[mid + 1].
96+
97+ 3. If nums[mid] > nums[mid + 1]:
98+ - Peak lies on the left side.
99+ - Move r = mid.
100+
101+ 4. Else:
102+ - Peak lies on the right side.
103+ - Move l = mid + 1.
104+
105+ 5. When l == r, that index is the peak.
106+
107+ ---
108+
109+ ## Dry Run
110+
111+ nums = [1,2,3,1]
112+
113+ Initial:
114+ l = 0, r = 3
115+
116+ mid = 1
117+ nums[1] = 2
118+ nums[2] = 3
119+
120+ 2 < 3
121+ => Peak is on right side
122+
123+ l = 2
124+
125+ Now:
126+ l = 2, r = 3
127+
128+ mid = 2
129+ nums[2] = 3
130+ nums[3] = 1
131+
132+ 3 > 1
133+ => Peak is on left side (including mid)
134+
135+ r = 2
136+
137+ Now:
138+ l = r = 2
139+
140+ Return 2
141+
142+ ---
143+
144+ ## Why Binary Search Works?
145+
146+ Whenever we compare nums[mid] and nums[mid + 1]:
147+
148+ - If the slope goes down, a peak exists on the left side.
149+ - If the slope goes up, a peak exists on the right side.
150+
151+ Since one half can always be discarded, binary search is applicable.
152+
153+ The search space reduces by half in every iteration.
154+
155+ ---
156+
157+ ## Time Complexity
158+
159+ Binary search halves the search space in every iteration.
160+
161+ Time Complexity: O(log n)
162+
163+ ---
164+
165+ ## Space Complexity
166+
167+ Only a few variables are used.
168+
169+ Space Complexity: O(1)
170+
171+ ---
172+
173+ ## LeetCode Solution
174+ """
175+
176+ from typing import List
177+
178+
179+ class Solution :
180+ def findPeakElement (self , nums : List [int ]) -> int :
181+ l = 0
182+ r = len (nums ) - 1
183+
184+ while l < r :
185+ mid = l + (r - l ) // 2
186+
187+ if nums [mid ] > nums [mid + 1 ]:
188+ r = mid
189+ else :
190+ l = mid + 1
191+
192+ return l
0 commit comments