Slot a New Booking Into a Sorted Calendar
Solve this ProblemA calendar holds booked time ranges in sorted order; no two of them overlap or touch. A new booking arrives. Add it to the calendar, combining it with every existing range it overlaps (ranges that merely touch at a single point also count as overlapping), and return the updated calendar, still sorted.
You could throw everything into a list, sort it and merge — but the calendar is already sorted. Because of that, the ranges fall into three groups around the new booking (entirely before it, overlapping it, entirely after it), and one linear pass is enough.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ calendar.length ≤ 12; each entry is [start, end] with 0 ≤ start < end ≤ 60 - ◆
The calendar is sorted by start, and its entries never overlap or touch (each start is strictly greater than the previous end) - ◆
newBooking is [start, end] with 0 ≤ start < end ≤ 60 - ◆
Ranges that overlap — including ranges that touch at a single point — are combined. Return the calendar after adding newBooking, still sorted and with no overlapping or touching ranges
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Add It, Then Sort and Merge Everything
BruteIgnore the fact that the calendar is already in order. Put the new booking in with the rest, sort all the ranges by start, and run the standard combine- overlapping-ranges sweep: keep a current range, extend it while the next range starts at or before its end, and store it when a gap appears. It is correct and short, but it pays for a full sort of ranges that were already sorted.
O(n log n)O(n)1class Solution {
2 public int[][] slotBooking(int[][] calendar, int[] newBooking) {
3 List<int[]> all = new ArrayList<>();
4 for (int[] range : calendar) all.add(new int[]{range[0], range[1]});
5 all.add(new int[]{newBooking[0], newBooking[1]});
6 all.sort((a, b) -> a[0] - b[0]);
7 List<int[]> result = new ArrayList<>();
8 int[] current = all.get(0);
9 for (int k = 1; k < all.size(); k++) {
10 int[] next = all.get(k);
11 if (next[0] <= current[1]) {
12 current[1] = Math.max(current[1], next[1]);
13 } else {
14 result.add(current);
15 current = next;
16 }
17 }
18 result.add(current);
19 return result.toArray(new int[0][]);
20 }
21}Optimal — One Pass: Copy Before, Merge Overlaps, Copy After
OptimalBecause the calendar is sorted and disjoint, the ranges split into three runs relative to the new booking. First run: ranges that end strictly before the new booking starts — copy them unchanged. Second run: ranges that start at or before the new booking's end — they all overlap it, so widen the new booking to cover each one (smaller start, larger end). Third run: everything else — copy unchanged. Insert the widened booking between the runs. Each range is looked at once, so the work is linear with no sorting.
O(n)O(n)1class Solution {
2 public int[][] slotBooking(int[][] calendar, int[] newBooking) {
3 List<int[]> result = new ArrayList<>();
4 int i = 0, n = calendar.length;
5 int start = newBooking[0], end = newBooking[1];
6 while (i < n && calendar[i][1] < start) result.add(calendar[i++]);
7 while (i < n && calendar[i][0] <= end) {
8 start = Math.min(start, calendar[i][0]);
9 end = Math.max(end, calendar[i][1]);
10 i++;
11 }
12 result.add(new int[]{start, end});
13 while (i < n) result.add(calendar[i++]);
14 return result.toArray(new int[0][]);
15 }
16}