Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

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).