Coding problem · Medium · Intervals

Find Free Meeting Slots

Medium Practical tasks Seen at Google, Microsoft, Calendly, Atlassian

A calendar service stores busy blocks as [start, end) in minutes from midnight. Blocks may overlap and are unsorted.

Given busy, the working day dayStart/dayEnd, and minLength, return all free slots [start, end) within the working day whose length is at least minLength, in chronological order. Busy blocks may extend outside the working day.

Example 1

Input: busy = [[540,600],[570,630],[720,780]], dayStart = 540, dayEnd = 1020, minLength = 30
Output: [[630,720],[780,1020]]
Explanation: 09:00–10:30 busy (merged), lunch 12:00–13:00.

Hints

Hint 1

Sort busy blocks by start and sweep with a cursor free_from = dayStart.

Hint 2

Each block either leaves a gap before it (start - free_from >= minLength) or extends the cursor to max(cursor, end).

Write and run your solution

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n log n) · Space O(n)

Sort by start, keep cursor = the earliest time not known to be busy (starting at dayStart). For each block, if it starts after the cursor, the gap [cursor, min(start, dayEnd)) is free — keep it if long enough; then move the cursor to max(cursor, end). Finally, the tail [cursor, dayEnd) is free. Clamping to the working day handles blocks that spill outside it.

Reference solution

function freeSlots(busy, dayStart, dayEnd, minLength) {
  const blocks = [...busy].sort((a, b) => a[0] - b[0]);
  const out = [];
  let cursor = dayStart;
  for (const [s, e] of blocks) {
    const gapEnd = Math.min(s, dayEnd);
    if (gapEnd - cursor >= minLength) out.push([cursor, gapEnd]);
    cursor = Math.max(cursor, e);
    if (cursor >= dayEnd) break;
  }
  if (dayEnd - cursor >= minLength) out.push([cursor, dayEnd]);
  return out;
}

Follow-up questions

  • Find slots free for all attendees (merge everyone's busy blocks first).
  • Handle time zones and recurring events.