Find Peak Element Using Binary Search in DSA Go - Time & Space Complexity
We want to understand how fast the binary search method finds a peak element in an array.
How does the number of steps change as the array gets bigger?
Analyze the time complexity of the following code snippet.
func findPeakElement(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := left + (right-left)/2
if nums[mid] < nums[mid+1] {
left = mid + 1
} else {
right = mid
}
}
return left
}
This code finds a peak element index by repeatedly narrowing the search range using binary search.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for loop that halves the search range each time.
- How many times: The loop runs until the search range is one element, about log base 2 of n times.
Each step cuts the array size roughly in half, so the number of steps grows slowly as the array grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 steps |
| 100 | About 7 steps |
| 1000 | About 10 steps |
Pattern observation: Doubling the input size adds only one extra step.
Time Complexity: O(log n)
This means the steps needed grow slowly, making the search very efficient even for large arrays.
[X] Wrong: "The loop runs n times because it looks at each element."
[OK] Correct: The loop does not check every element; it cuts the search space in half each time, so it runs much fewer times.
Understanding this time complexity shows you can use efficient search methods, a key skill in many coding challenges and real-world problems.
"What if we changed the array to be unsorted without any peak guarantee? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of a peak element
A peak element is one that is strictly greater than its neighbors on both sides (or only one side if at the boundary).Step 2: Apply this to binary search context
Binary search finds such an element by comparing middle elements with neighbors to decide which half to search next.Final Answer:
An element that is greater than its neighbors -> Option AQuick Check:
Peak element = greater than neighbors [OK]
- Thinking peak is smallest element
- Confusing peak with first or last element always
- Ignoring boundary conditions
nums?Solution
Step 1: Identify valid index range for array in Go
Array indices in Go start at 0 and end at len(nums)-1, so boundaries must be set accordingly.Step 2: Check each option for correct boundary initialization
left, right := 0, len(nums) - 1 correctly sets left=0 and right=len(nums)-1, covering full array indices.Final Answer:
left, right := 0, len(nums) - 1 -> Option BQuick Check:
Array indices 0 to len-1 [OK]
- Setting right to len(nums) (out of range)
- Starting left at 1 and missing first element
- Using negative indices
nums := []int{1, 3, 20, 4, 1, 0} using binary search peak finding?Solution
Step 1: Identify peak candidates in the array
Array: [1, 3, 20, 4, 1, 0]. 20 at index 2 is greater than neighbors 3 and 4, so it's a peak.Step 2: Confirm binary search finds index 2
Binary search compares mid elements and moves left or right until it finds peak at index 2.Final Answer:
2 -> Option CQuick Check:
Peak at index 2 with value 20 [OK]
- Choosing first or last element incorrectly
- Confusing index with value
- Not checking both neighbors
func findPeak(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := (left + right) / 2
if nums[mid] < nums[mid+1] {
left = mid + 1
} else {
right = mid - 1
}
}
return left
}Solution
Step 1: Analyze the binary search boundary updates
When nums[mid] >= nums[mid+1], peak is at mid or to the left, so right should be set to mid, not mid - 1 to avoid skipping mid.Step 2: Identify impact of wrong right update
Using right = mid - 1 skips mid, possibly missing the peak element.Final Answer:
The right boundary update should be right = mid, not mid - 1 -> Option AQuick Check:
Right boundary must include mid [OK]
- Setting right = mid - 1 and skipping mid
- Changing left incorrectly
- Wrong loop condition causing infinite loop
nums := []int{10, 20, 15, 2, 23, 90, 67}. Using binary search to find a peak element, which index will be returned and why?Solution
Step 1: Identify all peak candidates in the array
Array: [10, 20, 15, 2, 23, 90, 67]. Peaks are 20 at index 1 and 90 at index 5.Step 2: Understand binary search behavior
Binary search compares mid and mid+1; it will move towards the higher peak 90 at index 5.Step 3: Confirm returned index
Binary search will return index 5 where 90 is a peak greater than neighbors 23 and 67.Final Answer:
5, because 90 is a peak greater than neighbors 23 and 67 -> Option DQuick Check:
Binary search finds highest local peak at index 5 [OK]
- Assuming first or last element always peak
- Choosing smaller peak incorrectly
- Not understanding binary search direction
Ready to prove it?
Pass the test and this pattern moves unknown
