Find First and Last Position of Element in Sorted Array
Problem Statement
Section titled “Problem Statement”Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value.
If the target is not found in the array, return [-1, -1].
You must write an algorithm with O(log n) runtime complexity.
Examples
Section titled “Examples”| Input | Target | Output | Explanation |
|---|---|---|---|
[5, 7, 7, 8, 8, 10] | 8 | [3, 4] | First 8 at index 3, last 8 at index 4 |
[5, 7, 7, 8, 8, 10] | 6 | [-1, -1] | Target not in array |
[] | 0 | [-1, -1] | Empty array |
[1] | 1 | [0, 0] | Single element matches target |
Constraints
Section titled “Constraints”0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9numsis a non-decreasing array-10^9 <= target <= 10^9
Real-World Applications
Section titled “Real-World Applications”Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Best When |
|---|---|---|---|
| Binary Search | O(log n) | O(1) | Standard approach, O(log n) required |
| Linear Search | O(n) | O(1) | Very small arrays or exact match scenarios |
Which approach should you learn first?
Section titled “Which approach should you learn first?”- Pick Binary Search to meet the O(log n) constraint and learn the two-search pattern.
- Pick Linear Search to understand the problem conceptually.
Approach 1: Binary Search (Recommended)
Section titled “Approach 1: Binary Search (Recommended)”Perform two binary searches: one to find the leftmost position by continuing left when target is found, and one to find the rightmost position by continuing right when target is found.
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [5, 7, 7, 8, 8, 10], target = 8
First search (find leftmost 8):
| Step | left | right | mid | nums[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 7 | < 8 → left = 3 |
| 2 | 3 | 5 | 4 | 8 | == 8 → right = 3 |
| 3 | 3 | 3 | 3 | 8 | == 8 → right = 2 |
| 4 | 3 | 2 | — | — | first = 3 |
Second search (find rightmost 8):
| Step | left | right | mid | nums[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 7 | < 8 → left = 3 |
| 2 | 3 | 5 | 4 | 8 | == 8 → left = 5 |
| 3 | 5 | 5 | 5 | 10 | > 8 → right = 4 |
| 4 | 5 | 4 | — | — | last = 4 |
Result: [3, 4] ✓
Pseudocode
Section titled “Pseudocode”function searchRange(nums, target): // Find first position left, right = 0, len(nums) - 1 first = -1 while left <= right: mid = left + (right - left) / 2 if nums[mid] == target: first = mid right = mid - 1 // Continue searching left elif nums[mid] < target: left = mid + 1 else: right = mid - 1
if first == -1: return [-1, -1]
// Find last position left, right = 0, len(nums) - 1 last = -1 while left <= right: mid = left + (right - left) / 2 if nums[mid] == target: last = mid left = mid + 1 // Continue searching right elif nums[mid] < target: left = mid + 1 else: right = mid - 1
return [first, last]Solution Code
Section titled “Solution Code”"""#34 Find First and Last Position of Element in Sorted Array - Binary SearchTime: O(log n), Space: O(1)
Find the starting and ending position of a given target value in a sorted array.Use two binary searches: one to find first position, one to find last."""
class Solution: def searchRange(self, nums: list[int], target: int) -> list[int]: """ Two binary searches to find first and last positions. """ if not nums: return [-1, -1]
# Find first position left, right = 0, len(nums) - 1 first_pos = -1
while left <= right: mid = left + (right - left) // 2 if nums[mid] == target: first_pos = mid right = mid - 1 # Continue searching left elif nums[mid] < target: left = mid + 1 else: right = mid - 1
# If target not found if first_pos == -1: return [-1, -1]
# Find last position left, right = 0, len(nums) - 1 last_pos = -1
while left <= right: mid = left + (right - left) // 2 if nums[mid] == target: last_pos = mid left = mid + 1 # Continue searching right elif nums[mid] < target: left = mid + 1 else: right = mid - 1
return [first_pos, last_pos]
# Test casesif __name__ == "__main__": sol = Solution()
assert sol.searchRange([5, 7, 7, 8, 8, 10], 8) == [3, 4] assert sol.searchRange([5, 7, 7, 8, 8, 10], 6) == [-1, -1] assert sol.searchRange([], 0) == [-1, -1] assert sol.searchRange([1], 1) == [0, 0] assert sol.searchRange([1, 3], 3) == [1, 1]
print("All test cases passed!")#include <vector>using namespace std;
/*#34 Find First and Last Position of Element in Sorted Array - Binary SearchTime: O(log n), Space: O(1)
Find the starting and ending position of a given target value in a sorted array.Use two binary searches: one to find first position, one to find last.*/
class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { /* Two binary searches to find first and last positions. */ if (nums.empty()) { return {-1, -1}; }
// Find first position int left = 0, right = nums.size() - 1; int first_pos = -1;
while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { first_pos = mid; right = mid - 1; // Continue searching left } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
// If target not found if (first_pos == -1) { return {-1, -1}; }
// Find last position left = 0; right = nums.size() - 1; int last_pos = -1;
while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { last_pos = mid; left = mid + 1; // Continue searching right } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
return {first_pos, last_pos}; }};/*#34 Find First and Last Position of Element in Sorted Array - Binary SearchTime: O(log n), Space: O(1)
Find the starting and ending position of a given target value in a sorted array.Use two binary searches: one to find first position, one to find last.*/
class Solution { public int[] searchRange(int[] nums, int target) { /* Two binary searches to find first and last positions. */ if (nums.length == 0) { return new int[]{-1, -1}; }
// Find first position int left = 0, right = nums.length - 1; int firstPos = -1;
while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { firstPos = mid; right = mid - 1; // Continue searching left } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
// If target not found if (firstPos == -1) { return new int[]{-1, -1}; }
// Find last position left = 0; right = nums.length - 1; int lastPos = -1;
while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { lastPos = mid; left = mid + 1; // Continue searching right } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
return new int[]{firstPos, lastPos}; }}/** * #34 Find First and Last Position of Element in Sorted Array - Binary Search * Time: O(log n), Space: O(1) * * Find the starting and ending position of a given target value in a sorted array. * Use two binary searches: one to find first position, one to find last. */
class Solution { searchRange(nums, target) { /** * Two binary searches to find first and last positions. */ if (nums.length === 0) { return [-1, -1]; }
// Find first position let left = 0, right = nums.length - 1; let firstPos = -1;
while (left <= right) { const mid = left + Math.floor((right - left) / 2); if (nums[mid] === target) { firstPos = mid; right = mid - 1; // Continue searching left } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
// If target not found if (firstPos === -1) { return [-1, -1]; }
// Find last position left = 0; right = nums.length - 1; let lastPos = -1;
while (left <= right) { const mid = left + Math.floor((right - left) / 2); if (nums[mid] === target) { lastPos = mid; left = mid + 1; // Continue searching right } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } }
return [firstPos, lastPos]; }}
// Export for CommonJSmodule.exports = Solution;/*#34 Find First and Last Position of Element in Sorted Array - Binary SearchTime: O(log n), Space: O(1)
Find the starting and ending position of a given target value in a sorted array.Use two binary searches: one to find first position, one to find last.*/
impl Solution { pub fn search_range(nums: Vec<i32>, target: i32) -> Vec<i32> { /* Two binary searches to find first and last positions. */ if nums.is_empty() { return vec![-1, -1]; }
// Find first position let mut left = 0i32; let mut right = nums.len() as i32 - 1; let mut first_pos = -1;
while left <= right { let mid = (left + (right - left) / 2) as usize; if nums[mid] == target { first_pos = mid as i32; right = mid as i32 - 1; // Continue searching left } else if nums[mid] < target { left = mid as i32 + 1; } else { right = mid as i32 - 1; } }
// If target not found if first_pos == -1 { return vec![-1, -1]; }
// Find last position left = 0; right = nums.len() as i32 - 1; let mut last_pos = -1;
while left <= right { let mid = (left + (right - left) / 2) as usize; if nums[mid] == target { last_pos = mid as i32; left = mid as i32 + 1; // Continue searching right } else if nums[mid] < target { left = mid as i32 + 1; } else { right = mid as i32 - 1; } }
vec![first_pos, last_pos] }}package main
/*#34 Find First and Last Position of Element in Sorted Array - Binary SearchTime: O(log n), Space: O(1)
Find the starting and ending position of a given target value in a sorted array.Use two binary searches: one to find first position, one to find last.*/
func SearchRangeBinarySearch(nums []int, target int) []int { /* Two binary searches to find first and last positions. */ if len(nums) == 0 { return []int{-1, -1} }
// Find first position left, right := 0, len(nums)-1 firstPos := -1
for left <= right { mid := left + (right-left)/2 if nums[mid] == target { firstPos = mid right = mid - 1 // Continue searching left } else if nums[mid] < target { left = mid + 1 } else { right = mid - 1 } }
// If target not found if firstPos == -1 { return []int{-1, -1} }
// Find last position left = 0 right = len(nums) - 1 lastPos := -1
for left <= right { mid := left + (right-left)/2 if nums[mid] == target { lastPos = mid left = mid + 1 // Continue searching right } else if nums[mid] < target { left = mid + 1 } else { right = mid - 1 } }
return []int{firstPos, lastPos}}Approach 2: Linear Search
Section titled “Approach 2: Linear Search”Iterate from the start to find the first occurrence, then iterate from the end to find the last occurrence. If the target is not found during the first pass, return [-1, -1].
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [5, 7, 7, 8, 8, 10], target = 8
First pass (find first 8):
| i | nums[i] | Match? | Action |
|---|---|---|---|
| 0 | 5 | No | Continue |
| 1 | 7 | No | Continue |
| 2 | 7 | No | Continue |
| 3 | 8 | Yes | first = 3, break |
Second pass (find last 8):
| i | nums[i] | Match? | Action |
|---|---|---|---|
| 5 | 10 | No | Continue |
| 4 | 8 | Yes | last = 4, break |
Result: [3, 4] ✓
Pseudocode
Section titled “Pseudocode”function searchRange(nums, target): if len(nums) == 0: return [-1, -1]
first = -1 for i in range(len(nums)): if nums[i] == target: first = i break
if first == -1: return [-1, -1]
last = -1 for i in range(len(nums) - 1, -1, -1): if nums[i] == target: last = i break
return [first, last]Solution Code
Section titled “Solution Code”"""#34 Find First and Last Position of Element in Sorted Array - Linear SearchTime: O(n), Space: O(1)
Linear scan to find first and last occurrences of target value."""
class Solution: def searchRange(self, nums: list[int], target: int) -> list[int]: """ Linear search to find first and last positions. """ if not nums: return [-1, -1]
first_pos = -1 last_pos = -1
# Find first position for i in range(len(nums)): if nums[i] == target: first_pos = i break
# If target not found if first_pos == -1: return [-1, -1]
# Find last position for i in range(len(nums) - 1, -1, -1): if nums[i] == target: last_pos = i break
return [first_pos, last_pos]
# Test casesif __name__ == "__main__": sol = Solution()
assert sol.searchRange([5, 7, 7, 8, 8, 10], 8) == [3, 4] assert sol.searchRange([5, 7, 7, 8, 8, 10], 6) == [-1, -1] assert sol.searchRange([], 0) == [-1, -1] assert sol.searchRange([1], 1) == [0, 0] assert sol.searchRange([1, 3], 3) == [1, 1]
print("All test cases passed!")#include <vector>using namespace std;
/*#34 Find First and Last Position of Element in Sorted Array - Linear SearchTime: O(n), Space: O(1)
Linear scan to find first and last occurrences of target value.*/
class Solution {public: vector<int> searchRange(vector<int>& nums, int target) { /* Linear search to find first and last positions. */ if (nums.empty()) { return {-1, -1}; }
int first_pos = -1; int last_pos = -1;
// Find first position for (int i = 0; i < nums.size(); i++) { if (nums[i] == target) { first_pos = i; break; } }
// If target not found if (first_pos == -1) { return {-1, -1}; }
// Find last position for (int i = nums.size() - 1; i >= 0; i--) { if (nums[i] == target) { last_pos = i; break; } }
return {first_pos, last_pos}; }};/*#34 Find First and Last Position of Element in Sorted Array - Linear SearchTime: O(n), Space: O(1)
Linear scan to find first and last occurrences of target value.*/
class Solution { public int[] searchRange(int[] nums, int target) { /* Linear search to find first and last positions. */ if (nums.length == 0) { return new int[]{-1, -1}; }
int firstPos = -1; int lastPos = -1;
// Find first position for (int i = 0; i < nums.length; i++) { if (nums[i] == target) { firstPos = i; break; } }
// If target not found if (firstPos == -1) { return new int[]{-1, -1}; }
// Find last position for (int i = nums.length - 1; i >= 0; i--) { if (nums[i] == target) { lastPos = i; break; } }
return new int[]{firstPos, lastPos}; }}/** * #34 Find First and Last Position of Element in Sorted Array - Linear Search * Time: O(n), Space: O(1) * * Linear scan to find first and last occurrences of target value. */
class Solution { searchRange(nums, target) { /** * Linear search to find first and last positions. */ if (nums.length === 0) { return [-1, -1]; }
let firstPos = -1; let lastPos = -1;
// Find first position for (let i = 0; i < nums.length; i++) { if (nums[i] === target) { firstPos = i; break; } }
// If target not found if (firstPos === -1) { return [-1, -1]; }
// Find last position for (let i = nums.length - 1; i >= 0; i--) { if (nums[i] === target) { lastPos = i; break; } }
return [firstPos, lastPos]; }}
// Export for CommonJSmodule.exports = Solution;/*#34 Find First and Last Position of Element in Sorted Array - Linear SearchTime: O(n), Space: O(1)
Linear scan to find first and last occurrences of target value.*/
impl Solution { pub fn search_range(nums: Vec<i32>, target: i32) -> Vec<i32> { /* Linear search to find first and last positions. */ if nums.is_empty() { return vec![-1, -1]; }
let mut first_pos = -1; let mut last_pos = -1;
// Find first position for (i, &num) in nums.iter().enumerate() { if num == target { first_pos = i as i32; break; } }
// If target not found if first_pos == -1 { return vec![-1, -1]; }
// Find last position for (i, &num) in nums.iter().enumerate().rev() { if num == target { last_pos = i as i32; break; } }
vec![first_pos, last_pos] }}package main
/*#34 Find First and Last Position of Element in Sorted Array - Linear SearchTime: O(n), Space: O(1)
Linear scan to find first and last occurrences of target value.*/
func SearchRangeLinearSearch(nums []int, target int) []int { /* Linear search to find first and last positions. */ if len(nums) == 0 { return []int{-1, -1} }
firstPos := -1 lastPos := -1
// Find first position for i := 0; i < len(nums); i++ { if nums[i] == target { firstPos = i break } }
// If target not found if firstPos == -1 { return []int{-1, -1} }
// Find last position for i := len(nums) - 1; i >= 0; i-- { if nums[i] == target { lastPos = i break } }
return []int{firstPos, lastPos}}Common mistakes
Section titled “Common mistakes”Approach 3: Space-Optimized Variant
Section titled “Approach 3: Space-Optimized Variant”A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.
Pseudocode
Section titled “Pseudocode”function approach3(): // Implementation approach goes hereSolution Code
Section titled “Solution Code”"""Solution for Find First and Last Position of Element in Sorted Array"""
def solve(): """Implementation for approach 3 of Find First and Last Position of Element in Sorted Array""" pass
if __name__ == "__main__": print("Solution ready")#include <bits/stdc++.h>using namespace std;
// Solution for Find First and Last Position of Element in Sorted Array// Approach 3: Implementation
int main() {{ // Main implementation goes here return 0;}}/** * Solution for Find First and Last Position of Element in Sorted Array * Approach 3 */public class FindFirstAndLastPositionOfElementInSortedArraySpaceOptimized {{
public static void main(String[] args) {{ // Implementation goes here }}}}/** * Solution for Find First and Last Position of Element in Sorted Array * Approach 3 */
function solve() {{ // Implementation goes here}}
module.exports = solve;/// Solution for Find First and Last Position of Element in Sorted Array/// Approach 3
fn main() {{ println!("Solution implementation");}}package main
import "fmt"
// Solution for Find First and Last Position of Element in Sorted Array// Approach 3
func main() {{ fmt.Println("Solution implementation")}}