Find First and Last Position of Element
Problem Statement
Given a sorted array of integers and a target value, find the first and last positions of the target in the array. Return [-1, -1] if the target is not found. This is a medium-level problem that leverages binary search to achieve efficiency in a sorted array.
Example
Input: nums = [5, 7, 7, 8, 8, 10], target = 8
Output: [3, 4] (8 appears from index 3 to 4)
Input: nums = [5, 7, 7, 8, 8, 10], target = 6
Output: [-1, -1] (6 is not in the array)
Code
Java
Python
JavaScript
public class Solution { public int[] searchRange(int[] nums, int target) { int[] result = {-1, -1}; result[0] = findFirst(nums, target); if (result[0] != -1) { result[1] = findLast(nums, target); } return result; } private int findFirst(int[] nums, int target) { int left = 0, right = nums.length - 1; int first = -1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { first = mid; right = mid - 1; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return first; } private int findLast(int[] nums, int target) { int left = 0, right = nums.length - 1; int last = -1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { last = mid; left = mid + 1; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return last; } }
def search_range(nums, target): def find_first(nums, target): left, right = 0, len(nums) - 1 first = -1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: first = mid right = mid - 1 elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return first def find_last(nums, target): left, right = 0, len(nums) - 1 last = -1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: last = mid left = mid + 1 elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return last first = find_first(nums, target) last = find_last(nums, target) if first != -1 else -1 return [first, last] # Example usage print(search_range([5, 7, 7, 8, 8, 10], 8)) # [3, 4] print(search_range([5, 7, 7, 8, 8, 10], 6)) # [-1, -1]
function searchRange(nums, target) { function findFirst(nums, target) { let left = 0, right = nums.length - 1; let first = -1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (nums[mid] === target) { first = mid; right = mid - 1; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return first; } function findLast(nums, target) { let left = 0, right = nums.length - 1; let last = -1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (nums[mid] === target) { last = mid; left = mid + 1; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return last; } const first = findFirst(nums, target); const last = first !== -1 ? findLast(nums, target) : -1; return [first, last]; } // Example usage console.log(searchRange([5, 7, 7, 8, 8, 10], 8)); // [3, 4] console.log(searchRange([5, 7, 7, 8, 8, 10], 6)); // [-1, -1]
Explanation
- Use two binary searches: one to find the first occurrence, one for the last.
- For the first position, if target is found, search left half to find the earliest occurrence.
- For the last position, if target is found, search right half to find the latest occurrence.
- Adjust pointers based on whether mid element is less than, equal to, or greater than target.
- Return [-1, -1] if target isn’t found; otherwise, return the range.
Note
Time complexity is O(log n) due to two binary searches. Space complexity is O(1).