LeetCode 218. 天際線問題 (掃描線+優先隊列)

掃描線+優先隊列 https://leetcode-cn.com/problems/the-skyline-problem/solution/tian-ji-xian-wen-ti-by-leetcode-solution-ozse/

先把所有橫座標排序,然後把建築按橫座標排序。設定每個建築都包含左不包含有  [left,right) 這樣。然後對於每一個橫座標都先在優先隊列壓入包含它的建築

然後再從最高的點開始找,如何不包含該橫座標就彈出。然後剩下的建築中,都是包含該橫座標的,找最高的那個就是關鍵點。

要學習一下優先隊列自定義排序的寫法。

class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        // 優先隊列保存當前最大高度
        // 優先隊列 按高度排序
        auto cmp = [](const pair<int, int>& a, const pair<int, int>& b) -> bool { return a.second < b.second; };
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> q(cmp);

        vector<int> boundaries; // 保存所有橫座標
        for (auto &b: buildings) {
            boundaries.push_back(b[0]);
            boundaries.push_back(b[1]);
        }
        sort(boundaries.begin(), boundaries.end()); // 橫座標從小到達排序

        // buildings 按 lefti 非遞減排序 不需要再次排序
        vector<vector<int>> ret;
        int n = buildings.size(), idx = 0;
        for (auto & b: boundaries) {
            while (idx < n && buildings[idx][0] <= b) {
                q.emplace(buildings[idx][1], buildings[idx][2]);
                idx++;
            }
            while (!q.empty() && q.top().first <= b) {
                q.pop();
            }
            int maxh = q.empty() ? 0 : q.top().second;
            if (ret.empty() || maxh != ret.back()[1]) {
                ret.push_back({b, maxh});
            }
        }

        return ret;        
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章