Meeting Rooms II in Java (O(n log n) Time Complexity)


Given an array consisting of meeting time intervals, which are represented by the start and end times ([s0, e0], [s1, e1], ...], determine the minimum number of meeting rooms needed in order to be able to accommodate all meetings at every moment of time.


Example:

Input: [[5, 10], [0, 30], [15, 20]]
Output: 2
Explanation: 1st and 3rd meetings can be assigned to the first room
             2nd meeting can be assigned to room 2

 

Note:

  1. You may assume the interval's end point is always greater than its start point.
  2. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap.

Your algorithm should run in O(n log n) time and use O(n) extra space.


Understanding the Problem

The core challenge of this problem is to determine the minimum number of meeting rooms required to accommodate all meetings without any overlap. This problem is significant in scheduling and resource allocation scenarios, such as conference room booking systems.

Potential pitfalls include not accounting for meetings that end exactly when another starts, and not efficiently managing the intervals to minimize room usage.

Approach

To solve this problem, we can use a greedy algorithm with a priority queue (min-heap). The idea is to keep track of the end times of meetings currently using rooms and allocate new rooms as needed.

Initial naive solution: Iterate through each meeting and check for overlaps with all other meetings. This approach is not optimal as it has a time complexity of O(n^2).

Optimized solution: Use a priority queue to keep track of the earliest ending meeting. Sort the meetings by start time and iterate through them, using the priority queue to manage room allocation efficiently.

Algorithm

  1. Sort the meeting intervals by their start times.
  2. Initialize a priority queue (min-heap) to keep track of end times of meetings currently using rooms.
  3. Iterate through the sorted meeting intervals:
    • If the priority queue is not empty and the earliest ending meeting ends before the current meeting starts, remove the earliest ending meeting from the queue.
    • Add the current meeting's end time to the priority queue.
  4. The size of the priority queue at the end of the iteration will be the minimum number of meeting rooms required.

Code Implementation

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

public class MeetingRoomsII {
    public int minMeetingRooms(int[][] intervals) {
        // Edge case: if there are no meetings, no rooms are needed
        if (intervals == null || intervals.length == 0) {
            return 0;
        }

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

        // Initialize a priority queue to keep track of end times
        PriorityQueue<Integer> endTimes = new PriorityQueue<>();

        // Add the end time of the first meeting
        endTimes.add(intervals[0][1]);

        // Iterate through the remaining intervals
        for (int i = 1; i < intervals.length; i++) {
            // If the earliest ending meeting ends before the current meeting starts, remove it
            if (endTimes.peek() <= intervals[i][0]) {
                endTimes.poll();
            }

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

        // The size of the priority queue is the minimum number of meeting rooms required
        return endTimes.size();
    }

    public static void main(String[] args) {
        MeetingRoomsII solution = new MeetingRoomsII();
        int[][] intervals = {{5, 10}, {0, 30}, {15, 20}};
        System.out.println(solution.minMeetingRooms(intervals)); // Output: 2
    }
}

Complexity Analysis

The time complexity of this approach is O(n log n) due to the sorting step and the operations on the priority queue. The space complexity is O(n) because we store the end times of the meetings in the priority queue.

Edge Cases

Potential edge cases include:

Testing

To test the solution comprehensively, consider the following test cases:

Use a testing framework like JUnit to automate the testing process.

Thinking and Problem-Solving Tips

When approaching such problems, consider the following tips:

Conclusion

In this blog post, we discussed how to determine the minimum number of meeting rooms required to accommodate all meetings using a priority queue. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for efficient resource allocation and scheduling.

Additional Resources

For further reading and practice, consider the following resources: