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