1. 程式人生 > 實用技巧 >Map介面的實現類

Map介面的實現類

城市的天際線是從遠處觀看該城市中所有建築物形成的輪廓的外部輪廓。現在,假設您獲得了城市風光照片(圖A)上顯示的所有建築物的位置和高度,請編寫一個程式以輸出由這些建築物形成的天際線(圖B)。

每個建築物的幾何資訊用三元組[Li,Ri,Hi] 表示,其中 Li 和 Ri 分別是第 i 座建築物左右邊緣的 x 座標,Hi 是其高度。可以保證0 ≤ Li, Ri ≤ INT_MAX,0 < Hi ≤ INT_MAX 和 Ri - Li > 0。您可以假設所有建築物都是在絕對平坦且高度為 0 的表面上的完美矩形。

例如,圖A中所有建築物的尺寸記錄為:[ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] 。

輸出是以[ [x1,y1], [x2, y2], [x3, y3], ... ] 格式的“關鍵點”(圖B中的紅點)的列表,它們唯一地定義了天際線。關鍵點是水平線段的左端點。請注意,最右側建築物的最後一個關鍵點僅用於標記天際線的終點,並始終為零高度。此外,任何兩個相鄰建築物之間的地面都應被視為天際線輪廓的一部分。

例如,圖B中的天際線應該表示為:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]。

說明:

任何輸入列表中的建築物數量保證在 [0, 10000]範圍內。
輸入列表已經按左x 座標Li 進行升序排列。
輸出列表必須按 x 位排序。
輸出天際線中不得有連續的相同高度的水平線。例如 [...[2 3], [4 5], [7 5], [11 5], [12 7]...] 是不正確的答案;三條高度為 5 的線應該在最終輸出中合併為一個:[...[2 3], [4 5], [12 7], ...]

    

  

只考慮每個 building 的左上角和右上角座標,將所有點按x座標排序,然後開始遍歷。

需要一個優先佇列來儲存遍歷座標的高度,也就是 y 軸座標。

對於左上角座標和右上角座標有不同的處理方式。

遇到左上角座標,將其 y 座標加入到優先佇列中。

遇到右上角座標,將其 y 座標從優先佇列中刪除,也就是刪除了其對應的左上角座標的 y 值。

最後判斷優先佇列中的最高高度相對於之前是否更新,如果更新了的話,就將當前的x以及更新後的最高高度作為一個座標加入到最終結果中。

class Solution {
public:
    struct Node {
        int x;  //
x座標 int y; //y座標 }; static bool cmp(Node n1,Node n2) { //先按x座標排,x小的在前 if(n1.x != n2.x) { return n1.x < n2.x; } //畫圖舉例子,這幾種情況難理解 //如果相等:1、都為左座標,高的在前(y小);2、都為右座標,低的在前先刪無變化(y小);3、一左一右,左在前(左的y為負) return n1.y < n2.y; } vector<vector<int>> getSkyline(vector<vector<int>>& buildings) { vector<vector<int>> res; //先把輸入轉化成二維座標形式.(x,y)形式。每個輸入buildings有三個值,leftx rightx y。可拆分成2個座標 vector<Node> coordinate; //左座標的y值設為負,右座標值設為正。1區分左右,2排序時妙用。 for(int i=0;i<buildings.size();i++){ Node n1,n2; n1.x = buildings[i][0]; n1.y = -buildings[i][2]; n2.x = buildings[i][1]; n2.y = buildings[i][2]; coordinate.push_back(n1); coordinate.push_back(n2); } //將所有的座標排序 sort(coordinate.begin(),coordinate.end(),cmp); //藉助優先佇列存高度值(堆):當插入左座標或者刪除右座標,優先佇列有高度值變化,該x與優先佇列中y最大值即為一個節點 // priority_queue<int> p; // p.push(0); // int preMax = p.top(); //發現priority_queue沒法刪除指定值,因為刪除右座標時需要刪除其y。引入multiset,也是有序的,最後一個最大 multiset<int> s; s.insert(0); int preMax = *s.rbegin(); int maxCur = *s.rbegin(); for(int i=0;i<coordinate.size();i++){ vector<int> cor; //左座標 if(coordinate[i].y < 0){ s.insert(-coordinate[i].y); maxCur = *s.rbegin(); if(maxCur > preMax){ cor.push_back(coordinate[i].x); cor.push_back(maxCur); res.push_back(cor); } preMax = maxCur; } //右座標:刪除 if(coordinate[i].y > 0){ multiset<int>::iterator iter = s.find(coordinate[i].y); s.erase(iter); maxCur = *s.rbegin(); if(maxCur < preMax){ cor.push_back(coordinate[i].x); cor.push_back(maxCur); res.push_back(cor); } preMax = maxCur; } } return res; } };