class Solution:
    # test case :  5 7 7 8 8 10, t = 8 
    #               [1], 1  => [0,0]
    #               [1], 2 =>[-1,-1]
    #                1 2   2  =>
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        # edge case:  len(nums) == 1 or 0 
        # brute force: loop O(N)  
        # binary search + loop, or 1st + 2nd binary search 
        # time O(lgN) space O(1)
        def left_bound(nums,target):
            l, r = 0, len(nums)-1
            while l <= r :
                mid = l + (r-l)//2
                if nums[mid] < target:
                    l = mid + 1
                elif nums[mid] > target:
                    r = mid - 1
                elif nums[mid] == target:
                    # to close to left 
                    r = mid -1 
            if l >= len(nums) or nums[l] != target:
                return -1
            else:
                return l
            
        def right_bound(nums,target):
            l, r = 0, len(nums)-1
            while l <= r:
                mid = l + (r-l)//2
                if nums[mid] < target:
                    l = mid +1
                elif nums[mid] > target:
                    r = mid - 1
                elif nums[mid] == target:
                    # to close to right 
                    l  = mid + 1
            if r < 0 or nums[r] != target:
                return -1
            else:
                return r
        res = [left_bound(nums,target),right_bound(nums,target)]
        return res