Skip to main content

253. Meeting Rooms II

mediumAsked at Pinterest

Pinterest asks Meeting Rooms II because its scheduling / capacity-planning systems (and ads-pacing controllers) all reduce to 'max concurrent intervals.' Given a list of meeting intervals, return the minimum number of conference rooms required.

By Sam K., Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Pinterest loops.

  • Glassdoor (2026-Q1)Pinterest SWE onsite reports cite Meeting Rooms II as the interval / scheduling round.
  • LeetCode Pinterest tag (2026-Q1)Listed on the Pinterest company-tagged problem list.
  • Blind (2025-12)Pinterest L4 onsite reports mention this as a 30-minute heap question.

Problem

Given an array of meeting time intervals intervals where intervals[i] = [start_i, end_i], return the minimum number of conference rooms required.

Constraints

  • 1 <= intervals.length <= 10^4
  • 0 <= start_i < end_i <= 10^6

Examples

Example 1

Input
intervals = [[0,30],[5,10],[15,20]]
Output
2

Example 2

Input
intervals = [[7,10],[2,4]]
Output
1

Explanation: Non-overlapping intervals can share a room.

Approaches

1. Sort + sweep with min-heap of end times (optimal)

Sort by start. Min-heap holds end times of currently-occupied rooms. For each interval, if the earliest-ending room ends before this one starts, reuse it (pop). Otherwise allocate a new room. Heap size at the end = answer.

Time
O(n log n)
Space
O(n)
class MinHeap {
  constructor() { this.a = []; }
  push(v) { this.a.push(v); this._up(this.a.length - 1); }
  pop() {
    const top = this.a[0];
    const last = this.a.pop();
    if (this.a.length > 0) { this.a[0] = last; this._down(0); }
    return top;
  }
  peek() { return this.a[0]; }
  size() { return this.a.length; }
  _up(i) {
    while (i > 0) {
      const p = (i - 1) >> 1;
      if (this.a[p] > this.a[i]) {
        [this.a[p], this.a[i]] = [this.a[i], this.a[p]];
        i = p;
      } else break;
    }
  }
  _down(i) {
    const n = this.a.length;
    while (true) {
      const l = 2 * i + 1, r = 2 * i + 2;
      let best = i;
      if (l < n && this.a[l] < this.a[best]) best = l;
      if (r < n && this.a[r] < this.a[best]) best = r;
      if (best === i) break;
      [this.a[best], this.a[i]] = [this.a[i], this.a[best]];
      i = best;
    }
  }
}

function minMeetingRooms(intervals) {
  if (intervals.length === 0) return 0;
  intervals.sort((a, b) => a[0] - b[0]);
  const heap = new MinHeap();
  for (const [start, end] of intervals) {
    if (heap.size() > 0 && heap.peek() <= start) heap.pop();
    heap.push(end);
  }
  return heap.size();
}

Tradeoff: Standard interview answer. O(n log n) sort + O(n log n) heap ops. The 'reuse if earliest-ending room fits' line is the invariant — narrate it.

2. Two-pointer chronological sweep

Sort starts and ends independently. Walk both as event streams; +1 on a start, -1 on an end. Track the running max.

Time
O(n log n) for the two sorts
Space
O(n)
function minMeetingRoomsSweep(intervals) {
  const starts = intervals.map((x) => x[0]).sort((a, b) => a - b);
  const ends = intervals.map((x) => x[1]).sort((a, b) => a - b);
  let rooms = 0, max = 0, i = 0, j = 0;
  while (i < starts.length) {
    if (starts[i] < ends[j]) {
      rooms += 1;
      max = Math.max(max, rooms);
      i += 1;
    } else {
      rooms -= 1;
      j += 1;
    }
  }
  return max;
}

Tradeoff: No heap needed — just two sorted arrays. Some interviewers prefer this because it eliminates the heap dependency. Same asymptotic cost; cleaner inner loop.

Pinterest-specific tips

Pinterest interviewers like seeing the two-pointer sweep as the 'sneaky simpler' alternative. Volunteer both: write the heap version first (production-shaped, easy to extend to other follow-ups), then mention 'I could also do this with two sorted arrays and a single pass — same complexity, no heap.' That signals algorithmic flexibility.

Common mistakes

  • Using < vs <= for the heap-peek check inconsistently — at the boundary, a meeting ending exactly when another starts CAN share the room (end <= start means reuse).
  • Sorting by end time instead of start — fails on inputs where a long meeting starts first.
  • Two-pointer version: forgetting that the loop ends when starts is exhausted (ends is allowed to lag).
  • Returning the heap size instead of tracking max — same answer here because we never shrink below max, but it's a brittle pattern.

Follow-up questions

An interviewer at Pinterest may pivot to one of these next:

  • What if there's a fixed number of rooms and you must assign meetings (return assignment, not just count)?
  • Stream of meetings: maintain the current room count online.
  • Add room types (small/large) — meetings need a minimum room size.
  • Weighted intervals: maximize total weight of non-overlapping meetings (classic DP).

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why does Pinterest care about this specifically?

Ads-pacing controllers track concurrent in-flight requests; capacity planning for backend services models max concurrent operations. Both reduce to max-concurrent-intervals.

Is the two-pointer version really better than the heap?

Same asymptotic complexity, slightly smaller constants in practice. Pick whichever you find easier to reason about; the heap version generalizes more cleanly when the follow-up asks for the actual room assignment.

Free learning resources

Curated free links for this problem.

Companies that also ask Meeting Rooms II