[Leetcode] 253. Meeting Rooms II 解題報告

魔豆Magicbean發表於2017-07-03

題目

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.

思路

基本思路都是掃描線演算法,有幾個不同的實現版本:

1、一維向量:將整個intervals對映到一個一維向量中,並且用一個int值來標記是會議的開始還是結束(用0表示會議結束,用1表示會議開始,這樣在同一時間演算法會首先處理會議結束的情況),然後對這個一維向量中的資料進行排序。最後掃描一維向量,一旦發現某個會議結束,則會議室用量減1,否則加1。同時更新一下全域性最大辦公室用量。整個演算法的空間複雜度是O(n),時間複雜度是O(nlogn)。

2、multiset:這次是先對每個區間的起點排序,然後依次將每個區間的終點放在一個集合中。如果下一個區間的起點大於等於之前某個區間的終點,就將其從集合中刪除,每次需要統計一下當前所需的最大辦公室數量。這個版本的時間複雜度還是O(nlogn),但是空間複雜度卻變成output-dependent的了,最多是O(n),最少是O(1)。

3、map:我們用一個map來儲存重合區域,即每個區間的起點代表一個區間的開始,會將重疊區域+1,每個區間的結束點代表一個區間的結束,會將重疊區域-1。因此我們可以利用這個性質,結合STL中的map來實現(實質上這個演算法和“一維向量”版本非常像,只是採用的資料結構不同而已)。

程式碼

1、一維向量:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    int minMeetingRooms(vector<Interval>& intervals) {
        vector<pair<int, int>> meetings;
        int max_room = 0, crt_room = 0;
        for(int i = 0; i < intervals.size(); ++i) {
            meetings.push_back(make_pair(intervals[i].start, 1));
            meetings.push_back(make_pair(intervals[i].end, 0));
        }
        sort(meetings.begin(), meetings.end());
        for(int i = 0; i < meetings.size(); ++i) {
            if(meetings[i].second == 0) {
                --crt_room;
            }
            else {
                ++crt_room;
            }
            max_room = max(max_room, crt_room);
        }
        return max_room;
    }
};
2、multiset:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    int minMeetingRooms(vector<Interval>& intervals) {
        auto cmp = [](Interval a, Interval b) { return a.start < b.start; };
        sort(intervals.begin(), intervals.end(), cmp);
        multiset<int> ms;
        int max_room = 0;
        for (auto val : intervals) {
            while (!ms.empty() && val.start >= *ms.begin()) {
                ms.erase(ms.begin());
            }
            ms.insert(val.end);
            max_room = max(max_room, static_cast<int>(ms.size()));
        }
        return max_room;
    }
};
3、Map:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    int minMeetingRooms(vector<Interval>& intervals) {
        map<int, int> mp;
        for (auto val : intervals) {
            ++mp[val.start];
            --mp[val.end];
        }
        int max_room = 0, crt_room = 0;
        for (auto val : mp) {
            crt_room += val.second;
            max_room = max(max_room, crt_room);
        }
        return max_room;
    }
};

相關文章