Meeting Rooms II

update Aug 12, 2017 10:39

LeetCode

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.

Basic Idea:

这里 是非常好的分析。

基本思路就是对start时间和end时间分别排序,然后维持两个指针开始遍历两个数组。具体思路如下图所示(摘自leetcode discussion)

这种思路可以算作是:基于事件的分析

Java Code:

    /**
     * Definition for an interval.
     * public class Interval {
     *     int start;
     *     int end;
     *     Interval() { start = 0; end = 0; }
     *     Interval(int s, int e) { start = s; end = e; }
     * }
     */
    public class Solution {
        public int minMeetingRooms(Interval[] intervals) {
            if (intervals == null || intervals.length == 0) return 0;
            int[] starts = new int[intervals.length];
            int[] ends = new int[intervals.length];
            for (int i = 0; i < intervals.length; ++i) {
                starts[i] = intervals[i].start;
                ends[i] = intervals[i].end;
            }
            Arrays.sort(starts);
            Arrays.sort(ends);
            int count = 0;
            int i = 0, j = 0;
            while (i < starts.length) {
                if (starts[i] < ends[j]) {
                    // 说明当前情况下没有新的会议结束,即无空房,要开新房
                    count++;
                    i++;
                } else {
                    // 说明有之前开始的某场会议已经结束,可以使用之前的房间
                    i++;
                    j++;
                }
            }
            return count;
        }
    }

update Sep 16 2018, 13:58

Update: 扫描线法

这个方法的本质和之前是一样的,也是将start和end平等对待,将其当做两种事件。先将每个时间点拿出来,标记为start或者end,然后将他们一起排序。之后从左往右扫描,遇到start就记为overlap+1,遇到end就记为overlap-1,返回值就是历史上最大的overlap数量。但是需要注意的是如果出现一个start和end在同一时间出现,我们需要保证end出现在start的前面,所以需要特别定制comparator的规则。

Java Code:

class Solution {
    private class Event {
        int time;
        boolean start;
        public Event(int time, boolean start) {
            this.time = time;
            this.start = start;
        }
    }
    public int minMeetingRooms(Interval[] intervals) {
        Event[] arr = new Event[intervals.length * 2];
        for (int i = 0; i < intervals.length; ++i) {
            arr[2 * i] = new Event(intervals[i].start, true);
            arr[2 * i + 1] = new Event(intervals[i].end, false);
        }
        Arrays.sort(arr, (a, b)->{
                if (a.time != b.time) {
                    return Integer.compare(a.time, b.time);
                } else if (a.start) {
                    return 1;
                } else return -1;
            });
        int maxOverlap = 0, overlap = 0;
        for (int i = 0; i < arr.length; ++i) {
            if (arr[i].start) {
                overlap++;
                maxOverlap = Math.max(maxOverlap, overlap);
            } else {
                overlap--;
            }
        }
        return maxOverlap;
    }
}

results matching ""

    No results matching ""