给定一组区间,找到具有最大交集数量的区间(而不是特定交集的长度)。 因此,如果输入为 (1,6) (2,3) (4,11),则应返回 (1,6)。 有人建议使用区间树以在O(nlogn)中完成此操作,但我在阅读其维基页面后并不理解如何构建和使用区间树。 我相信可以通过进行某种排序和扫描算法来完成它。 如果区间树是唯一选择,请教我如何构建/使用。 谢谢。
给定一组区间,找到具有最大交集数量的区间(而不是特定交集的长度)。 因此,如果输入为 (1,6) (2,3) (4,11),则应返回 (1,6)。 有人建议使用区间树以在O(nlogn)中完成此操作,但我在阅读其维基页面后并不理解如何构建和使用区间树。 我相信可以通过进行某种排序和扫描算法来完成它。 如果区间树是唯一选择,请教我如何构建/使用。 谢谢。
C(i)=-1-num_stop_events_so_far
,对于停止事件:C(i)+=num_start_events_so_far
。这不是更简单吗? - Evgeny Kluev注意:David Eisenstat的算法比这个更优秀。
一个简单的平面扫描算法可以在O(nlogn + m*n)
时间内完成,其中m
是任何单个区间与其他区间相交的最大数量。
首先对区间的端点进行排序。跟踪活动段。当到达起始点时,增加所有活动区间的相交计数,并将新区间的相交计数设置为活动区间的数量(不包括自身)。当到达结束点时,从活动区间中删除该区间。
m
项可能会被 log n
项主导。 - Snefteldef max_interval_count(intervals):
interval_sorted = []
for idx, interval in enumerate(intervals):
s, e = interval
interval_sorted.append([s, idx, 0]) # 0 for start
interval_sorted.append([e, idx, 1]) # 1 for end
interval_sorted.sort(key = lambda x: x[0])
print(interval_sorted)
number_of_starts = 0
number_of_ends = 0
overlap_count = {}
for event in interval_sorted:
_, idx, start_end = event
if start_end == 0: # start event
# subtract all the ending before it
overlap_count[idx] = - (number_of_ends)
number_of_starts += 1
else: # end event
overlap_count[idx] += (number_of_starts - 1) # -1 as we should not include the start from the same interval
number_of_ends += 1
print(overlap_count)
ans_idx = -1
max_over_count = 0
min_len_interval = 99999999999
for idx, overl_cnt in overlap_count.items():
if overl_cnt > max_over_count:
ans_idx = idx
max_over_count = overl_cnt
elif overl_cnt == max_over_count and overl_cnt > 0 and (intervals[idx][1] - intervals[idx][0] + 1) < min_len_interval:
min_len_interval = (intervals[idx][1] - intervals[idx][0] + 1)
ans_idx = idx
if ans_idx == -1:
return ans_idx
return intervals[ans_idx]
if __name__ == "__main__":
test_1 = [[1,5],[5,10],[5,5]]
test_2 = [[1,2],[3,5]]
test_3 = [(1,6), (2,3), (4,11)]
ans = max_interval_count(test_1)
print(ans)
print("---------")
ans = max_interval_count(test_2)
print(ans)
print("---------")
ans = max_interval_count(test_3)
print(ans)
print("---------")
[[1, 0, 0], [5, 0, 1], [5, 1, 0], [5, 2, 0], [5, 2, 1], [10, 1, 1]]
{0: 0, 1: 1, 2: 1}
[5, 5]
---------
[[1, 0, 0], [2, 0, 1], [3, 1, 0], [5, 1, 1]]
{0: 0, 1: 0}
-1
---------
[[1, 0, 0], [2, 1, 0], [3, 1, 1], [4, 2, 0], [6, 0, 1], [11, 2, 1]]
{0: 2, 1: 1, 2: 1}
(1, 6)
---------
O(n)
的时间复杂度下完成这个任务,因为你需要评估所有的区间。 - Vincent van der Weele