One efficient approach is to build an interval tree where all nodes to the left of a node have intervals lower than or equal to the lower bound of the node, and all nodes to the right of the node have intervals greater than or equal to the upper bound of the node so that adding an interval to the tree has an average time complexity of O(log n), and construction of the tree overall takes O(n log n) on average.
Since the goal is to retain non-overlapping intervals, we can make an insertion raise an exception to reject an overlapping interval:
class Interval:
def __init__(self, lower_bound, upper_bound):
self.lower_bound = lower_bound
self.upper_bound = upper_bound
class NonOverlappingIntervalTree:
def __init__(self):
self.interval = None
self.left = None
self.right = None
def add_interval(self, lower_bound, upper_bound):
if not self.interval:
self.interval = Interval(lower_bound, upper_bound)
return
if upper_bound <= self.interval.lower_bound:
if not (node := self.left):
node = self.left = NonOverlappingIntervalTree()
elif lower_bound >= self.interval.upper_bound:
if not (node := self.right):
node = self.right = NonOverlappingIntervalTree()
else:
raise ValueError
node.add_interval(lower_bound, upper_bound)
so your filter function can just skip an interval when it is found to overlap an existing node in the interval tree when attempting to add it to the tree:
def cut_overlapping_ranges(ranges):
output = []
tree = NonOverlappingIntervalTree()
for lower_bound, upper_bound, *data in ranges:
try:
tree.add_interval(lower_bound, upper_bound)
except ValueError:
continue
output.append([lower_bound, upper_bound, *data])
return output
so that:
cut_overlapping_ranges([[0, 10], [5, 15], [11, 18], [10, 25], [20, 25], [30, 35]])
outputs:
[[0, 10], [11, 18], [20, 25], [30, 35]]
Demo: https://ideone.com/vv48Oh
temp_ranges} while iterating over it . Additionally, you're not checking for the case where range_2 completely contains range_1.temp_rangeswhile you iterate over it, Also note,temp_ranges = rangesdoesn't create a copy, so you are mutating the input list