https://leetcode.com/problems/find-peak-element/description/
Tag: Array/List, Binary Search
Key Points:
The log(n) complexity implies the binary search in most cases
This condition is crucial when deciding which side to choose during binary search
<aside> š”
nums[i] != nums[i + 1]
Ā for all validĀ i
.
</aside>
Use the binary search template to prevent accidental infinite loop
If a point is not a peak:
Pay special attention to boundary conditions when:
def findPeakElement(self, nums: List[int]) -> int:
if not nums:
return -1
if len(nums) == 1:
return 0
left, right = 0, len(nums) - 1
while left + 1 < right:
# Python integer addition won't overflow. For other language,
# it's suggested to write as: mid = left + (right - left) // 2
mid = (left + right) // 2
if self.isPeak(nums, mid):
return mid
# mid is not peak because its left candidate is larger,
# the peak will be on its left side. Note when mid = 0 and it's not peak,
# the only reason would be its larger right neighbor.
# That is caught by the second elif below and need no special handling
elif mid > 0 and nums[mid - 1] > nums[mid]:
right = mid
elif mid < len(nums) - 1 and nums[mid + 1] > nums[mid]:
left = mid
else:
raise Exception("Invalid input")
if self.isPeak(nums, left):
return left
else:
return right
def isPeak(self, nums, idx):
# Handle the boundary condition
if idx == 0:
return nums[idx] > nums[1]
elif idx == len(nums) - 1:
return nums[idx - 1] < nums[idx]
else:
return nums[idx] > max(nums[idx-1], nums[idx+1])