边工作边刷题:70天一遍leetcode: day 35-4
Search for a Range
这两题的考点都是bounded binary search (i.e., > or >=), 程序结构要点:
- mid的更新在loop的最后,所以开始要初始化
- 条件是low<high,而不是low<=high, 否则可能infinite loop,因为low或者high可能不变,比如[1,3], 1:e.g., for >=: [4], mid0, low0, high0, target=3, 因为循环后low没有变化。同样这个例子说明为什么mid要在loop最后更新:lowhigh就跳出循环
- 对于low=mid, mid lean to high: mid = (low+high+1)/2
对于range这题,value不存在的corner cases还是比较复杂。首先,bounded binary search选择’>’ or ‘<‘,而不是’>=’ or ‘<=‘。这是因为如果>=,返回的左右边界不能用一个条件来判断是否是target的边界。另外,target超过左右边界元素的任意一个,都返回[-1,-1]。另一种情况是target就在边界上,这个corner case是在binary search里面处理,返回-1 or len(nums),这样在主函数里就可以用同一个公式判断target是否存在。
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
def binary_right(nums, target):
if target>=nums[-1]: return len(nums)
low,high=0,len(nums)-1
mid = low+(high-low)/2
while low<high:
if nums[mid]>target:
high=mid
else:
low=mid+1
mid = low+(high-low)/2
return mid
def binary_left(nums, target):
if target<=nums[0]: return -1
low,high=0,len(nums)-1
mid = (high+low+1)/2
while low<high:
if nums[mid]<target:
low=mid
else:
high=mid-1
mid = (high+low+1)/2
return mid
left,right = 0,0
if not nums or nums[-1]<target or nums[0]>target:
return [-1,-1]
right=binary_right(nums, target)
left=binary_left(nums, target)
print "left=",left,"right=",right
if nums[right-1]==target and nums[left+1]==target:
return [left+1, right-1]
return [-1,-1]