一种简单的方法是使用树形结构。树的根将具有整个列表的最小值/最大值。然后它将有两个孩子,它们给出前半部分和后半部分的最小值/最大值等。这将允许您使用 O(log(n)) 搜索算法,其中 n 是整个区间列表的大小。
首先,您构建树。这可以通过将区间列表分成两部分并为每个子区间制作一棵树来递归完成:
def makeTree(begin,end,intervals):
if end==begin:
return None
if end==begin+1:
return Node(begin,end,intervals[begin],None,None)
partition=(begin+end)/2
left=makeTree(begin,partition)
right=makeTree(partition,end)
range=combineRanges(rangeOf(left),rangeOf(right))
return Node(begin,end,range,left,right)
一旦你有了树,你可以将树的根传递给这个函数:
def findRange(node,begin,end):
# If the node's range doesn't intersect the range you are looking for,
# then you don't have to look any deeper.
if node is None or begin>=node.end or end<=node.begin:
return None
# If the node's range is completely inside the range you are looking for, then
# you also don't need to look any deeper.
if begin<=node.begin and end>=node.end:
return node.range
# Otherwise, check each child.
left_range=findRange(node.left,begin,end)
right_range=findRange(node.right,begin,end)
# And return the combined result.
return combineRanges(left_range,right_range)
请注意,我使用的是半开区间,对于区间中的任何 x,begin <= x < end。这只是使代码更干净一些。