标准二分搜索出现在leetcode704. 二分查找
def search(nums: List[int], left: int, right: int, target: int) -> int:
while left < right:
# 选择中位数时下取整
mid = left + (right - left) // 2
if check(mid):
# 下一轮搜索区间是 [mid + 1, right]
left = mid + 1
else:
# 下一轮搜索区间是 [left, mid]
right = mid
# 退出循环的时候,程序只剩下一个元素没有看到。
# 视情况,是否需要单独判断 left(或者 right)这个下标的元素是否符合题意
现在是二分搜索模板
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right = 0,len(nums)-1
if left == right: return 0 if target==nums[0] else -1
while left < right:
# 选择中位数时下取整
mid = left + (right - left) // 2
#if nums[mid]==target: return mid
if nums[mid]<target:
# 下一轮搜索区间是 [mid + 1, right]
left = mid + 1
else:
# 下一轮搜索区间是 [left, mid]
right = mid
return left if nums[left]==target else -1
# 退出循环的时候,程序只剩下一个元素没有看到。
# 视情况,是否需要单独判断 left(或者 right)这个下标的元素是否符合题意
然后是实际运用中的二分搜索
class TimeMap:
def __init__(self):
"""
Initialize your data structure here.
"""
self.store = collections.defaultdict(list)
def set(self, key: str, value: str, timestamp: int) -> None:
#if key not in store:
self.store[key].append((timestamp,value))
.
def get(self, key: str, timestamp: int) -> str:
if key not in self.store or self.store[key][0][0]>timestamp: return ""
cur = self.store[key]
n = len(cur)
l,r = 0,n-1
while l < r:
mid = l+ (r-l)//2
if cur[mid][0] == timestamp: return cur[mid][1]
if cur[mid][0] < timestamp:
l = mid+1
else:
r = mid
if cur[r][0]> timestamp:
return cur[r-1][1]
return cur[r][1]
# Your TimeMap object will be instantiated and called as such:
# obj = TimeMap()
# obj.set(key,value,timestamp)
# param_2 = obj.get(key,timestamp)
使用过程中注意二分搜索的范围问题,就此题来说,当left 向右边扩展时候 可能越边界,所以要 l-1
python中同样有非常好的二分模块: bisect, 返回对应元素的下标,这里边bisect.bisect_right 和 bisect.bisect是一样的
bisect.bisect_left 返回的插入点 i 可以将数组 a 分成两部分。左侧是 all(val < x for val in a[lo:i])
,右侧是 all(val >= x for val in a[i:hi])
。
只有当a中已经存在点x时候才会有影响。
bisect.insort, 等同于 insert(bisect.bisect(list,val),val)
使用 bisect重写题目:
class TimeMap:
def __init__(self):
"""
Initialize your data structure here.
"""
self.store = {}
def set(self, key: str, value: str, timestamp: int) -> None:
if key not in self.store:
self.store[key]=[[timestamp],[value]]
else:
self.store[key][0].append(timestamp)
self.store[key][1].append(value)
def get(self, key: str, timestamp: int) -> str:
if key not in self.store or self.store[key][0][0]>timestamp: return ""
cur = self.store[key]
index = bisect.bisect(cur[0],timestamp)
return cur[1][index-1]
#
# Your TimeMap object will be instantiated and called as such:
# obj = TimeMap()
# obj.set(key,value,timestamp)
# param_2 = obj.get(key,timestamp)