以前我就想过类似的题目,结果思路不对……现在再来一次吧
我的思路是,保存一个区间左右两边的数字。例如,对于区间[2, 5],那么现在我们就保存 2 和 5.
如果我们拿到了6,那么查表,存在 5 的话,就把 5 删除。如果 5 不存在,那么就把 6 保存,且标记为 leftmost 的数字。
那么如何实现这个方案呢?
首先考虑如何维护一个区间。
搞一个字典好了,而且要求这个字典有序。
那么当我们获得一个数字 n 的时候:
* x = get n-1, y = get n+1
* 如果 x 存在,且 x 是一个 rightmost 的数,则把 x 的 rightmost 属性删掉。在这个过程中,某个数的属性可能会全都被删掉,但是我们依然将其保留在字典里,避免在区间内重复建立区间。
* 如果 x 不存在,那么将 n 插入字典,且将其属性设为 leftmost。
* 对于 y 也是同理。
最后,当我们要查询的时候,就遍历这个有序字典,然后根据属性建立区间。
有些
1 from sortedcontainers import SortedDict 2 class SummaryRanges: 3 4 def __init__(self): 5 self.d = SortedDict() 6 self.LEFT = 2 # 0x10 7 self.RIGHT = 1 # 0x01 8 9 10 def addNum(self, val: int) -> None: 11 if val in self.d: 12 return 13 14 # note that 0 <= val <= 10^4 15 l = val - 1 16 r = val + 1 17 18 if l >= 0 and l in self.d and (self.d[l] & self.RIGHT): 19 self.d[l] = self.d[l] & self.LEFT # delete l as rightmost number 20 21 elif l not in self.d: 22 self.d[val] = self.d.get(val, 0) | self.LEFT # set val as leftmost number 23 24 if r <= 10000 and r in self.d and (self.d[r] & self.LEFT): 25 self.d[r] = self.d[r] & self.RIGHT 26 27 elif r not in self.d: 28 self.d[val] = self.d.get(val, 0) | self.RIGHT 29 30 def getIntervals(self) -> List[List[int]]: 31 ret = [] 32 temp = [] 33 for k in self.d: 34 if self.d[k] == self.LEFT: 35 temp.append(k) 36 elif self.d[k] == self.RIGHT: 37 temp.append(k) 38 ret.append(temp) 39 temp = [] 40 elif self.d[k] == self.LEFT | self.RIGHT: 41 ret.append([k, k]) 42 return ret
这个办法因为每次都要重新建立一次区间结果,所以时间和空间的效率上不是很好。