Skip to content

Commit b79630f

Browse files
committed
feat(algorithms, intervals): merge and insert intervals
1 parent 9d24af5 commit b79630f

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Insert Interval
2+
3+
You are given a list of non-overlapping intervals, intervals, where each interval is represented as [starti, endi] and
4+
the list is sorted in ascending order by the start of each interval (starti). You are also given another interval,
5+
new_interval = [start, end].
6+
7+
Your task is to insert new_interval into the list of intervals such that the list remains sorted by starting times and
8+
still contains no overlapping intervals. If any intervals overlap after the insertion, merge them accordingly.
9+
10+
Return the updated list of intervals.
11+
12+
> Note You don’t need to modify intervals in place. You can make a new array and return it.
13+
14+
## Constraints
15+
16+
- 0 ≤ `intervals.length` ≤ 10^4
17+
- `intervals[i].length`, `new_interval.length` == 2
18+
- 0 ≤ `starti` < `endi` ≤ 10^4
19+
- The list of intervals is sorted in ascending order based on the start time
20+
21+
## Examples
22+
23+
![Example 1](./images/examples/insert_interval_example_1.png)
24+
![Example 2](./images/examples/insert_interval_example_2.png)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from typing import List
2+
3+
4+
def insert_interval(existing_intervals: List[List[int]], new_interval: List[int]):
5+
"""
6+
Inserts the new interval into the list of existing intervals and return the updated list of intervals. This assumes
7+
that the existing_intervals array is already sorted by the start time.
8+
Args:
9+
existing_intervals (List[List[int]]): A list of intervals, where each interval is represented as a list of two integers [start, end].
10+
new_interval (List[int]): A new interval to be inserted into the list of existing intervals.
11+
Returns:
12+
List[List[int]]: The updated list of intervals after inserting the new interval.
13+
"""
14+
# no intervals to insert
15+
if not existing_intervals:
16+
return [new_interval]
17+
result = []
18+
i = 0
19+
n = len(existing_intervals)
20+
new_start, new_end = new_interval
21+
22+
# add all intervals that come completely before the new interval
23+
while i < n and existing_intervals[i][1] < new_start:
24+
result.append(existing_intervals[i])
25+
i += 1
26+
27+
# merge all intervals that overlap with the new interval
28+
merged_start = new_start
29+
merged_end = new_end
30+
31+
# add all intervals that come completely after the new interval
32+
while i < n and existing_intervals[i][0] <= merged_end:
33+
# Update merged-start and merged_end
34+
merged_start = min(merged_start, existing_intervals[i][0])
35+
merged_end = max(merged_end, existing_intervals[i][1])
36+
i += 1
37+
38+
# add the merged interval
39+
result.append([merged_start, merged_end])
40+
41+
# add all intervals that come completely after the new interval
42+
while i < n:
43+
result.append(existing_intervals[i])
44+
i += 1
45+
46+
return result
46.3 KB
Loading
38.9 KB
Loading
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
from typing import List
3+
from parameterized import parameterized
4+
from algorithms.intervals.insert_interval import insert_interval
5+
6+
7+
class InsertIntervalTestCase(unittest.TestCase):
8+
@parameterized.expand(
9+
[
10+
([[1, 2], [3, 4], [5, 8], [9, 15]], [2, 5], [[1, 8], [9, 15]]),
11+
(
12+
[[1, 6], [8, 9], [10, 15], [16, 18]],
13+
[9, 10],
14+
[[1, 6], [8, 15], [16, 18]],
15+
),
16+
(
17+
[[1, 2], [3, 4], [5, 8], [9, 15]],
18+
[16, 17],
19+
[[1, 2], [3, 4], [5, 8], [9, 15], [16, 17]],
20+
),
21+
([[1, 4], [5, 6], [7, 8], [9, 10]], [1, 5], [[1, 6], [7, 8], [9, 10]]),
22+
([[1, 3], [4, 6], [7, 8], [9, 10]], [1, 10], [[1, 10]]),
23+
([[1, 3], [5, 7], [8, 9], [10, 13]], [2, 6], [[1, 7], [8, 9], [10, 13]]),
24+
([[1, 3], [6, 9]], [2, 5], [[1, 5], [6, 9]]),
25+
]
26+
)
27+
def test_insert_interval(
28+
self,
29+
existing_intervals: List[List[int]],
30+
new_interval: List[int],
31+
expected: List[List[int]],
32+
):
33+
actual = insert_interval(existing_intervals, new_interval)
34+
self.assertEqual(expected, actual)
35+
36+
37+
if __name__ == "__main__":
38+
unittest.main()

0 commit comments

Comments
 (0)