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 are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).

leetcode218 - The Skyline Problem - hard_第1张图片   leetcode218 - The Skyline Problem - hard_第2张图片

The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX0 < Hi ≤ INT_MAX, and Ri - 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 position Li.
  • 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:
    vectorint>> getSkyline(vectorint>>& buildings) {
        
        vectorint>> res;
        vectorint,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; } };

 

 

你可能感兴趣的:(leetcode218 - The Skyline Problem - hard)