问题描述:
给定一个按时间开始从小到大排序的时间区间集合,这些时间区间之间不存在重叠。
时间区间集合用一个二维数组表示,二维数组的每一行表示一个时间区间,其中0位置的元素表示开始时刻的小时数,1位置元素表示开始时刻的分钟数,2位置元素表示结束时刻的小时数,3位置元素表示结束时刻的分钟数。
例如:
[(18, 30, 19, 40)] 表示18:30-19:40这段时间。
[(15, 0, 16, 20), (18, 30, 19, 40)] 表示15:00-16:20和18:30-19:40这两段时间。
现在在给定一个时刻,要求判断这个时刻是否在这时间区间范围内。
例1
输入:
时间区间集合=[(15, 0, 16, 20), (18, 30, 19, 20), (20, 10, 20, 30)]
时刻=(16, 10)
返回:true
解释:16:10在15:00-16:20这段时间内
例2
输入:
时间区间集合=[(15, 0, 16, 20), (18, 30, 19, 20), (20, 10, 20, 30)]
时刻=(16, 30)
返回:false
解释:16:30在(15:00-16:20, 18:30-19:20, 20:10-20:30)中的任何一段时间范围内
例3
输入:
时间区间集合=[(15, 0, 16, 20), (18, 30, 19, 20), (20, 10, 20, 30)]
时刻=(18, 30)
返回:true
解释:18:30在(18:30-19:20)这段时间内
二分查找
方法描述:因为时间区间是从小到大的并且区间之间没有重叠。所以,采用二分查找,先找中间是否符合,不符合就判断时刻在中间时间段的左侧或者右侧,继续查找。
核心代码:
def binarySearch(time_list, time, left, right, mark = True):
'''
二分查找:
:param time_list: [], 形如[(15, 0, 16, 20), (18, 30, 19, 20), (20, 10, 20, 30)], 记录时刻区间
:param time: [], 形如(18, 30), 记录查找的时刻
:param left: int, 查找的开始位置
:param right: int, 查找的结束位置
:param mark: bool, 布尔型,第一轮计算出查找time的分钟数,此后不必重复计算
:return: bool, 查找结果
'''
if mark:
time = time[0] * 60 + time[1]
mid = (right + left)//2
start_h, start_m, end_h, end_m = time_list[mid]
start = start_h * 60 + start_m
end = end_h * 60 + end_m
if start <= time and time <= end:
return True
elif mid >= right or mid <= left: # 边界条件:如果mid此时是right(最后一个时间段),上次比较未返回True,则返回False; left同理
return False
if start > time:
return binarySearch(time_list, time, left, mid - 1, False)
else:
return binarySearch(time_list, time, mid + 1, right, False)
例子:
time_list = [(15,0,16,20), (18,30,19,20), (20, 10, 20, 30), (21, 10, 22, 10)]
time = (22, 30)
binarySearch(time_list, time, left = 0, right = len(time_list))
如果各位大佬还有其他方法,也欢迎讨论。
在飞的小猪