Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals.
For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ..., then the summary will be:
[1, 1] [1, 1], [3, 3] [1, 1], [3, 3], [7, 7] [1, 3], [7, 7] [1, 3], [6, 7]
题目 提供两个接口添加一个数字和返回所有数字区间。
相对简单,添加数字时二分法查找,如果需要合并(这是一个新的数字n且n-1,n+1在现有数字区间内)的话就合并一下。代码如下:
class SummaryRanges(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.intervals = []
def addNum(self, val):
"""
:type val: int
:rtype: None
"""
if len(self.intervals) == 0:
self.intervals = [[val,val]]
elif val >= self.intervals[-1][1]: #如果在收尾可以简单处理
if val <= self.intervals[-1][1]+1:
self.intervals[-1][1] = val
else:
self.intervals.append([val,val])
elif val <= self.intervals[0][0]-1:
if val >= self.intervals[0][0]-1:
self.intervals[0][0] = val
else:
self.intervals.insert(0,[val,val])
else:
#在中间一般处理,二分查找
s = 0
e = len(self.intervals) - 1
m = (s + e)//2
while s < e:
small,big = self.intervals[m]
if val >= small and val <= big: #已经在现有区间内了
return
if val == small -1:
if m > 0 and val == self.intervals[m-1][1]+1:#需要合并,下同
self.intervals[m-1][1] = self.intervals[m][1]
self.intervals.pop(m)
else:
self.intervals[m][0] = val
return
if val == big + 1:
if m < len(self.intervals) - 1 and val == self.intervals[m+1][0]-1:
self.intervals[m+1][0] = self.intervals[m][0]
self.intervals.pop(m)
else:
self.intervals[m][1] = val
return
if val < small:
e = m
elif val > big:
s = m + 1
m = (s+e)//2
small,big = self.intervals[m]
if val >= small and val <= big:
return
if val == small -1:
if m > 0 and val == self.intervals[m-1][1]+1:#合并
self.intervals[m-1][1] = self.intervals[m][1]
self.intervals.pop(m)
return
else:
self.intervals[m][0] = val
elif val == big + 1:
if m < len(self.intervals) - 1 and val == self.intervals[m+1][0]-1:
self.intervals[m+1][0] = self.intervals[m][0]
self.intervals.pop(m)
return
else:
self.intervals[m][1] = val
else:
self.intervals.insert(m,[val,val])
def getIntervals(self):
"""
:rtype: List[List[int]]
"""
return self.intervals
# Your SummaryRanges object will be instantiated and called as such:
# obj = SummaryRanges()
# obj.addNum(val)
# param_2 = obj.getIntervals()