Taro Logo

Meeting Rooms II

Medium
Meta logo
Meta
1 view
Topics:
ArraysGreedy AlgorithmsDynamic Programming

You are given an array of meeting time intervals, where each interval consists of a start time and an end time. Your task is to determine the minimum number of conference rooms required to accommodate all the meetings without any overlaps. Each meeting needs its own room during the interval, and a room can be reused only after the previous meeting has ended.

Input: An array of meeting time intervals, represented as int[][] intervals, where intervals[i] = [start_time, end_time]. Assume start_time < end_time for each interval.

Examples:

  1. Input: intervals = [[0, 30], [5, 10], [15, 20]] Output: 2 Explanation:

    • Meeting 1: [0, 30]
    • Meeting 2: [5, 10]
    • Meeting 3: [15, 20] Two conference rooms are needed. Meeting 1 occupies a room from time 0 to 30. Meeting 2 can start in another room at time 5 and ends at 10. Meeting 3 can also start in the second room as it begins after Meeting 2 has ended (starts at 15, ends at 20).
  2. Input: intervals = [[7, 10], [2, 4]] Output: 1 Explanation:

    • Meeting 1: [7, 10]
    • Meeting 2: [2, 4] One conference room is sufficient, as the meetings do not overlap.
  3. Input: intervals = [[1, 5], [8, 9], [8, 9]] Output: 2 Explanation:

    • Meeting 1: [1, 5]
    • Meeting 2: [8, 9]
    • Meeting 3: [8, 9] Since the start times of meeting 2 and meeting 3 are the same, they will need to be in different rooms, since they cannot occur at the same time in the same room.

Constraints:

  • 0 <= intervals.length <= 10000
  • intervals[i].length == 2
  • 0 <= intervals[i][0] < intervals[i][1] <= 10^6

Can you write a function to efficiently calculate the minimum number of conference rooms required?

Solution


Meeting Rooms II

Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required.

For example,

Given [[0, 30],[5, 10],[15, 20]], return 2.

Naive Solution

A naive solution would be to iterate through all the intervals and for each interval, check if it overlaps with any of the existing rooms. If it doesn't overlap, we can assign it to an existing room. If it overlaps with all existing rooms, we need to create a new room. This approach is inefficient because it requires comparing each interval with all existing rooms.

Optimal Solution

The optimal solution involves sorting the intervals by their start times and then using a min-heap to track the end times of the meetings in progress. The min-heap allows us to efficiently find the meeting that ends earliest.

Here's a step-by-step breakdown:

  1. Sort the intervals: Sort the intervals by their start times. This ensures that we process meetings in the order they begin.
  2. Initialize a min-heap: Create a min-heap (priority queue) to store the end times of the meetings currently in progress. The root of the heap will always be the meeting that ends earliest.
  3. Iterate through the sorted intervals:
    • For each interval, check if the start time of the current meeting is greater than or equal to the earliest ending time in the min-heap (the root of the heap).
      • If it is, it means the earliest ending meeting has finished, and we can reuse that room. Remove the earliest ending time from the heap.
      • If it isn't, it means the current meeting overlaps with existing meetings, and we need a new room.
    • Add the end time of the current meeting to the min-heap.
  4. The size of the min-heap at the end represents the minimum number of conference rooms required.

Edge Cases

  • Empty input: If the input array is empty, return 0.
  • Null input: Handle the case where the input array is null.
  • Overlapping intervals: The algorithm correctly handles overlapping intervals.
  • Non-overlapping intervals: The algorithm correctly handles non-overlapping intervals.
  • Single interval: If there's only one interval, return 1.

Code

import java.util.Arrays;
import java.util.PriorityQueue;

public class MeetingRoomsII {

    public int minMeetingRooms(int[][] intervals) {
        if (intervals == null || intervals.length == 0) {
            return 0;
        }

        // Sort the intervals by start time
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));

        // Use a min-heap to track the end times of merged intervals
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();

        // Add the first meeting to the heap
        minHeap.add(intervals[0][1]);

        // Iterate through the remaining meetings
        for (int i = 1; i < intervals.length; i++) {
            // If the current meeting starts after the earliest ending meeting,
            // then we can reuse a room
            if (intervals[i][0] >= minHeap.peek()) {
                minHeap.poll();
            }

            // Add the current meeting's end time to the heap
            minHeap.add(intervals[i][1]);
        }

        // The size of the heap is the number of rooms required
        return minHeap.size();
    }

    public static void main(String[] args) {
        MeetingRoomsII meetingRooms = new MeetingRoomsII();

        // Example usage
        int[][] intervals1 = {{0, 30}, {5, 10}, {15, 20}};
        System.out.println("Minimum meeting rooms required: " + meetingRooms.minMeetingRooms(intervals1)); // Output: 2

        int[][] intervals2 = {{7,10},{2,4}};
         System.out.println("Minimum meeting rooms required: " + meetingRooms.minMeetingRooms(intervals2)); // Output: 1

        int[][] intervals3 = {{1,5},{8,9},{8,9}};
        System.out.println("Minimum meeting rooms required: " + meetingRooms.minMeetingRooms(intervals3)); // Output: 2
    }
}

Big O Runtime

  • Sorting: O(n log n), where n is the number of intervals.
  • Iterating through the intervals: O(n).
  • Heap operations (add and poll): O(log n) for each operation, and we perform at most n operations. So it would be O(n log n).

Therefore, the overall time complexity is O(n log n).

Big O Space

  • The space complexity is dominated by the min-heap, which can store at most n end times in the worst case. Therefore, the space complexity is O(n).