Find First and Last Position of Element in Sorted Array in Python

Finding the first and last position of an element in a sorted array is a classic problem that can be efficiently solved using binary search. Given a sorted array and a target value, we need to return the starting and ending indices of the target. If the target is not found, we return [-1, -1].

For example, if the array is [2,2,2,3,4,4,4,4,5,5,6] and target is 4, the output should be [4,7] since 4 appears from index 4 to index 7.

Algorithm

We use two binary searches to find the leftmost and rightmost positions ?

  • First binary search finds the leftmost occurrence of the target
  • Second binary search finds the rightmost occurrence of the target
  • If target is not found, return [-1, -1]

Implementation

def search_range(nums, target):
    def find_first():
        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
        return first_pos
    
    def find_last():
        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 last_pos
    
    first = find_first()
    if first == -1:
        return [-1, -1]
    
    last = find_last()
    return [first, last]

# Test the function
nums = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6]
target = 4
result = search_range(nums, target)
print(f"Array: {nums}")
print(f"Target: {target}")
print(f"First and last position: {result}")
Array: [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6]
Target: 4
First and last position: [4, 7]

Alternative Implementation Using Single Function

Here's a more compact approach that finds both positions in one function ?

def search_range_compact(nums, target):
    def binary_search(find_first):
        left, right = 0, len(nums) - 1
        result = -1
        
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                result = mid
                if find_first:
                    right = mid - 1  # Search left half
                else:
                    left = mid + 1   # Search right half
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return result
    
    first = binary_search(True)
    if first == -1:
        return [-1, -1]
    
    last = binary_search(False)
    return [first, last]

# Test with different examples
test_cases = [
    ([2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6], 4),
    ([1, 2, 3, 4, 5], 3),
    ([1, 2, 3, 4, 5], 6),
    ([5, 7, 7, 8, 8, 10], 8)
]

for nums, target in test_cases:
    result = search_range_compact(nums, target)
    print(f"Array: {nums}, Target: {target} ? {result}")
Array: [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 6], Target: 4 ? [4, 7]
Array: [1, 2, 3, 4, 5], Target: 3 ? [2, 2]
Array: [1, 2, 3, 4, 5], Target: 6 ? [-1, -1]
Array: [5, 7, 7, 8, 8, 10], Target: 8 ? [3, 4]

Time and Space Complexity

  • Time Complexity: O(log n) where n is the length of the array
  • Space Complexity: O(1) as we only use constant extra space

Conclusion

Using binary search twice allows us to find both the first and last positions of a target element in O(log n) time. The key is to continue searching left after finding the target for the first position, and searching right for the last position.

Updated on: 2026-03-25T07:45:41+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements