1. 程式人生 > 實用技巧 >leetcode218 - The Skyline Problem - hard

leetcode218 - The Skyline Problem - hard

A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you aregiven the locations and height of all the buildingsas shown on a cityscape photo (Figure A), write a program tooutput the skylineformed by these buildings collectively (Figure B).

The geometric information of each building is represented by a triplet of integers[Li, Ri, Hi], whereLiandRiare the x coordinates of the left and right edge of the ith building, respectively, andHiis its height. It is guaranteed that0 ≤ Li, Ri ≤ INT_MAX,0 < Hi ≤ INT_MAX, andRi - Li > 0

. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.

For instance, the dimensions of all buildings in Figure A are recorded as:[ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ].

The output is a list of "key points" (red dots in Figure B) in the format of[ [x1,y1], [x2, y2], [x3, y3], ... ]

that uniquely defines a skyline.A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.

For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].

Notes:

  • The number of buildings in any input list is guaranteed to be in the range[0, 10000].
  • The input list is already sorted in ascending order by the left x positionLi.
  • The output list must be sorted by the x position.
  • There must be no consecutive horizontal lines of equal height in the output skyline. For instance,[...[2 3], [4 5], [7 5], [11 5], [12 7]...]is not acceptable; the three lines of height 5 should be merged into one in the final output as such:[...[2 3], [4 5], [12 7], ...]
key points出現在什麼時候呢?當現在的max height不等於之前的max height時。 邊界條件: 1. leaving point和entering point的x一樣時,先處理entering point:把entering point的height設成負的 2. entering points的x一樣,先處理最高的:一樣的把entering points的height設成負的,越高的h變得越小 3. leaving points的x一樣,先處理最矮的 這裡決定了排序順序 用什麼data structure?我們得add entering points, remove leaving points, 還有得隨時提出max來,那就是結合了hash table和heap->STL提供了multiset(balanced BST的思路),add/remove O(logn), max O(1) process: 1. 加一個entering point的時候,如果maxHeight高了,那我現在就是最高的 2. 刪掉一個leaving point的時候,如果maxHeight低了,那我剛剛是最高的,現在到另一個相對最高點了;相反如果maxHeight沒變,說明這一段有別的建築shadow我 細節: multiset裡一開始得放個0,注意看圖上兩組建築群中間也有個key point multiset裡存放的height都是正的 ***刪的時候,先找到對應的index再刪,因為multiset裡是有多個一樣的element的 get max - rbegin()指的值 key points的高度都是curMaxHeight 複雜度: Time O(nlogn) Space O(n) 別的方法:customize一個heap,使得heap的remove從n優化到logn 實現:
class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        
        vector<vector<int>> res;
        vector<pair<int,int>> pts;
        
        for (auto b : buildings){
            pts.emplace_back(b[0], -b[2]); //entering point
            pts.emplace_back(b[1], b[2]); //leaving point
        }      
        sort(pts.begin(), pts.end());
multiset
<int> ms; ms.insert(0); int maxHeight = 0; for (auto p : pts){ if (p.second < 0) ms.insert(-p.second); else ms.erase(ms.find(p.second)); int curMaxHeight = *ms.rbegin(); if (curMaxHeight != maxHeight){ res.push_back({p.first, curMaxHeight}); maxHeight = curMaxHeight; } } return res; } };