[Leetcode] Meeting Rooms 會議室

Meeting Rooms

Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings.ui

For example, Given [[0, 30],[5, 10],[15, 20]], return false.code

排序法

複雜度

時間 O(NlogN) 空間 O(1)排序

思路

這題和Merge Intervals很像,咱們按開始時間把這些Interval都給排序後,就挨個檢查是否有衝突就好了。有衝突的定義是開始時間小於以前最晚的結束時間。這裏以前最晚的結束時間不必定是上一個的結束時間,因此咱們更新的時候要取最大值。get

代碼

public class Solution {
    public boolean canAttendMeetings(Interval[] intervals) {
        if(intervals == null || intervals.length == 0) return true;
        Arrays.sort(intervals, new Comparator<Interval>(){
            public int compare(Interval i1, Interval i2){
                return i1.start - i2.start;
            }
        });
        int end = intervals[0].end;
        // 檢查每個Interval
        for(int i = 1; i < intervals.length; i++){
            // 若是Interval的開始時間小於以前最晚的結束時間,就返回假
            if(intervals[i].start < end) return false;
            end = Math.max(end, intervals[i].end);
        }
        return true;
    }
}

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.string

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

貪心法

複雜度

時間 O(NlogN) 空間 O(1)io

思路

這題的思路和Rearrange array to certain distance很像,咱們要用貪心法,即從第一個時間段開始,選擇下一個最近不衝突的時間段,再選擇下一個最近不衝突的時間段,直到沒有更多。而後若是有剩餘時間段,開始爲第二個房間安排,選擇最先的時間段,再選擇下一個最近不衝突的時間段,直到沒有更多,若是還有剩餘時間段,則開闢第三個房間,以此類推。這裏的技巧是咱們不必定要遍歷這麼多遍,咱們實際上能夠一次遍歷的時候就記錄下,好比第一個時間段咱們放入房間1,而後第二個時間段,若是和房間1的結束時間不衝突,就放入房間1,不然開闢一個房間2。而後第三個時間段,若是和房間1或者房間2的結束時間不衝突,就放入房間1或者2,不然開闢一個房間3,依次類推,最後統計開闢了多少房間。對於每一個房間,咱們只要記錄其結束時間就好了,這裏咱們查找不衝突房間時,只要找結束時間最先的那個房間。
這裏還有一個技巧,若是咱們把這些房間看成List來管理,每次查詢須要O(N)時間,若是咱們用堆來管理,能夠用logN時間找到時間最先結束的房間。ast

代碼

public class Solution {
    public int minMeetingRooms(Interval[] intervals) {
        if(intervals == null || intervals.length == 0) return 0;
        Arrays.sort(intervals, new Comparator<Interval>(){
            public int compare(Interval i1, Interval i2){
                return i1.start - i2.start;
            }
        });
        // 用堆來管理房間的結束時間
        PriorityQueue<Integer> endTimes = new PriorityQueue<Integer>();
        endTimes.offer(intervals[0].end);
        for(int i = 1; i < intervals.length; i++){
            // 若是當前時間段的開始時間大於最先結束的時間,則能夠更新這個最先的結束時間爲當前時間段的結束時間,若是小於的話,就加入一個新的結束時間,表示新的房間
            if(intervals[i].start >= endTimes.peek()){
                endTimes.poll();
            }
            endTimes.offer(intervals[i].end);
        }
        // 有多少結束時間就有多少房間
        return endTimes.size();
    }
}
相關文章
相關標籤/搜索