Intervals
51 / 170IntervalsLesson 5 of 6About 62 min
Stop thinking about intervals. Think about the moments things start and stop, in order.
The same sweep is often written without building an event list, by sorting starts and ends into two separate arrays and walking them with two indexes. Whichever time comes next decides whether the count rises or falls.
It avoids allocating pairs and reads well once you have seen it. The event-list version generalizes better, because an event can carry extra information such as which interval it belongs to.
The walk itself is the same whatever you are counting. Below it records, for each start, how many intervals had already finished by then.
def finished_before_each_start(intervals): starts = sorted(pair[0] for pair in intervals) ends = sorted(pair[1] for pair in intervals) counts = [] end_index = 0 for start in starts: while end_index < len(ends) and ends[end_index] <= start: end_index += 1 # this one was already over counts.append(end_index) return counts print(finished_before_each_start([[0, 30], [5, 10], [15, 20]]))There is a sixth problem in this family that asks, for each of many queries, the size of the smallest interval covering it. It needs a structure that can hand you the smallest thing currently available, which is a heap, so it waits until Unit 9.
The sweep you just learned is half of that solution. When you meet it there, the other half will be the only new part.
build_events turns intervals into a sorted event list of (time, change) pairs with ends before starts at equal times. time_with_at_least returns the total time during which at least k intervals are active. count_overlapping_pairs returns how many pairs of intervals overlap at all.
Tests
data = [[0, 30], [5, 10], [15, 20]]print(build_events([[1, 3], [3, 5]]))print(time_with_at_least(data, 1), time_with_at_least(data, 2), time_with_at_least(data, 3))print(count_overlapping_pairs(data), count_overlapping_pairs([]), count_overlapping_pairs([[1, 2], [1, 2], [1, 2]]))print(count_overlapping_pairs([[1, 3], [3, 5]]))Output
Run tests to see output.
Read the constraints first and let them tell you what complexity is expected. Derive the approach, implement it, run the tests, and submit when it passes.