package com.fishercoder.solutions; import java.util.Arrays; import java.util.PriorityQueue; public class _253 { public static class Solution1 { public int minMeetingRooms(int[][] intervals) { if (intervals == null || intervals.length == 0) { return 0; } // Sort the intervals by start time Arrays.sort(intervals, (a, b) -> a[0] - b[0]); // Use a min heap to track the minimum end time of merged intervals PriorityQueue<int[]> heap = new PriorityQueue<>(intervals.length, (a, b) -> a[1] - b[1]); // start with the first meeting, put it to a meeting room heap.offer(intervals[0]); for (int i = 1; i < intervals.length; i++) { // get the meeting room that finishes earliest int[] interval = heap.poll(); if (intervals[i][0] >= interval[1]) { // if the current meeting starts right after // there's no need for a new room, merge the interval interval[1] = intervals[i][1]; } else { // otherwise, this meeting needs a new room heap.offer(intervals[i]); } // don't forget to put the meeting room back heap.offer(interval); } return heap.size(); } } public static class Solution2 { /** * I'm so glad to have come up with this solution completely on my own on 10/13/2021. * Drawing on a piece of paper helps A LOT! It helps visualize your thoughts and clear the ambiguity up! */ public int minMeetingRooms(int[][] intervals) { //I use the meeting's end time as the room indicate and put them into a heap PriorityQueue<Integer> rooms = new PriorityQueue<>(); Arrays.sort(intervals, (a, b) -> a[0] - b[0]); for (int i = 0; i < intervals.length; i++) { if (rooms.isEmpty()) { rooms.add(intervals[i][1]); } else { if (rooms.peek() > intervals[i][0]) { //if the room that becomes available the earliest still cannot accommodate this new meeting, then we'll have to add a new room rooms.add(intervals[i][1]); } else { //otherwise, we'll just update the room that finishes the earliest with the new finish time. rooms.poll(); rooms.add(intervals[i][1]); } } } return rooms.size(); } } }