package com.freetymekiyan.algorithms.level.medium;

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

/**
 * 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.
 * <p>
 * For example,
 * Given [[0, 30],[5, 10],[15, 20]],
 * return 2.
 * <p>
 * Company Tags: Google Facebook
 * Tags: Heap, Greedy, Sort
 * Similar Problems: (H) Merge Intervals, (E) Meeting Rooms
 */
public class MeetingRooms2 {

    /**
     * Sort. Heap. Greedy.
     * Always put the next starting meeting after the first ending meeting.
     * If the start time overlaps with the nearest end time, need a new room.
     * So, sort the meetings according to start time first.
     * Then for each interval in the array:
     * | If min heap is not empty or start time doesn't overlap with first ending time:
     * |   Poll first ending time from the heap.
     * | Add the ending time for current meeting.
     */
    public int minMeetingRooms(Interval[] intervals) {
        if (intervals == null || intervals.length == 0) {
            return 0;
        }
        Arrays.sort(intervals, (i1, i2) -> i1.start - i2.start);
        PriorityQueue<Integer> firstEnd = new PriorityQueue<>();
        for (Interval i : intervals) {
            if (!firstEnd.isEmpty() && i.start >= firstEnd.peek()) {
                firstEnd.poll();
            }
            firstEnd.add(i.end);
        }
        return firstEnd.size();
    }

    /**
     * Interval class provided by leetcode.
     */
    public class Interval {

        int start;
        int end;

        Interval() {
            start = 0;
            end = 0;
        }

        Interval(int s, int e) {
            start = s;
            end = e;
        }
    }
}

@@ -56,62 +56,176 @@
 ort 
-java.util.Arrays;%0Aimport java.util.PriorityQueue;%0A%0A/**
+com.freetymekiyan.algorithms.utils.Utils.Interval;%0A%0Aimport java.util.Arrays;%0Aimport java.util.PriorityQueue;%0Aimport java.util.Queue;%0A%0A/**%0A * 252. Meeting Rooms 2%0A * %3Cp%3E
 %0A * 
@@ -1330,24 +1330,16 @@
         
-Priority
 Queue%3CIn
@@ -1635,81 +1635,460 @@
   * 
-Interval class provided by leetcode.%0A     */%0A    public class Interval %7B%0A
+Sort.%0A     * Sort all starts and ends separately.%0A     * Then merge them with 2 pointers.%0A     * When a new meeting starts, increment count of rooms by 1.%0A     * When an old meeting ends, decrement count of rooms by 1.%0A     * Record the maximum count.%0A     * Stop when all meeting started.%0A     */%0A    public int minMeetingRooms2(Interval%5B%5D intervals) %7B%0A        if (intervals == null %7C%7C intervals.length %3C 1) return 0;%0A        int n = intervals.length;
 %0A   
@@ -2095,22 +2095,38 @@
      int
+%5B%5D
  start
+s = new int%5Bn%5D
 ;%0A      
@@ -2134,120 +2134,294 @@
  int
+%5B%5D
  end
+s = new int%5Bn%5D
 ;%0A
-%0A
+ 
        
- Interval() %7B%0A            start = 0;%0A            end = 0;%0A        %7D%0A%0A        Interval(int s, int e
+for (int i = 0; i %3C n; i++) %7B%0A            starts%5Bi%5D = intervals%5Bi%5D.start;%0A            ends%5Bi%5D = intervals%5Bi%5D.end;%0A        %7D%0A        Arrays.sort(starts);%0A        Arrays.sort(ends);%0A        int rooms = 0;%0A        int j = 0;%0A        for (int i = 0; i %3C n; i++
 ) %7B%0A
@@ -2436,17 +2436,40 @@
     
+if (
 start
- = s
+s%5Bi%5D %3C ends%5Bj%5D) rooms++
 ;%0A  
@@ -2483,14 +2483,15 @@
    e
-nd = e
+lse j++
 ;%0A  
@@ -2502,12 +2502,33 @@
   %7D%0A
+        return rooms;%0A
     %7D%0A%7D
-%0A

update 252. Meeting Rooms 2 with new solution