也就是说每一次都要判别至少3个值。
最后是应该剩两个值。
#34 Search for a Range
Given an array of integers nums
sorted in non-decreasing order, find the starting and ending position of a given target
value.
If target
is not found in the array, return [-1, -1]
.
You must write an algorithm with O(log n)
runtime complexity.
解题思路:
排除edge case,nums里没有元素。
有两大类可能,一类nums里没有target,最后left pointer 和 right pointer会汇合,这种情况直接输出[-1, -1];另一类有target,中值早晚会等于target,这个时候寻找最左端left pointer等于target的,右同。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if len(nums) > 0:
l, r = 0, len(nums)-1
else:
return [-1, -1]
while r > l:
m = (l + r)//2
if nums[m] > target: # target is on the left
r = m - 1
elif nums[m] < target: # target is on the right
l = m + 1
else: # nums[m] == target
while True: # get l
if m > 0:
m = m - 1
if nums[m] != target:
l = m + 1
break
else:
l = m
break
while True: # get r
if m < len(nums)-1:
m = m + 1
if nums[m] != target:
r = m - 1
break
else:
r = m
break
break
if nums[l] == target:
return [l, r]
else:
return [-1, -1]
runtime:
64ms solution sample:
运用了python内置的Bisect Algorithm Functions。给定list和target后,用bisect_left()和bisect_right()找出插入target后依然保持sorted list的index。
import bisect
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
# if use built-in function
if nums == None or len(nums) == 0:
return [-1, -1]
def find(arr, target):
low, high = 0, len(arr)-1
while low <= high:
mid = low + (high-low)//2
if arr[mid] == target:
return True
elif arr[mid] > target:
high = mid - 1
else:
low = mid + 1
return False
if not find(nums, target):
return [-1, -1]
left = bisect.bisect_left(nums, target)
right = bisect.bisect_right(nums, target)
return [left, right-1]
这种方法相比之下的优点在于,一旦出现中值等于target时,利用bisect的特点寻找左右端的index值。如果一直没出现就输出[-1, -1]。