• [LeetCode]The Skyline Problem


    题目:The Skyline Problem

    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).

                                         

    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], ...]

    题目的意思:

    一个城市的skyline是从远处观看的城市中所有建筑物的外部轮廓。现在假设你给出了所有建筑物的位置和高度,如城市照片(图A)所示,写一个程序来输出由这些建筑物组成的skyline(图B)。
    每个建筑物的几何信息由整数三元组[Li,Ri,Hi]表示,其中Li和Ri分别是第i栋建筑物左右边缘的x坐标,Hi是其高度。可以保证0≤Li,Ri≤Int_MAX,0 <Hi≤INT_MAX,Ri-Li> 0。您可以假设所有建筑物都是在高度为0的绝对平坦的地面上的完美矩形。

    1. 任何输入列表中的建筑物数量保证在[0,10000]的范围内。
    2. 输入列表已经按左x位置李按升序排序。
    3. 输出列表必须按x位置排序。
    4. 输出skyline中不得有相等高度的连续水平线。例如[... [2 3],[4 5],[7 5],[11 5],[12 7] ...]是不能接受的;高度5的三行应该在最终输出中合并为一个:[... [2 3],[4 5],[12 7],...]

    思路:

    观察发现,建筑的坐标是分上升和下降的;上升趋势的坐标[ [2 10], [3 15] ],它是由当前建筑的L坐标和高度组成;下降趋势的坐标[ [7 12], [12 0]],[ [15 10], [20 8], [24, 0] ],它是由前一个高度的R坐标和后一个高度组成;

    那么可以将整个求解过程分成上升和下降两个过程:

    1. 上升时每次看是否有更高的建筑,有的话将他的L坐标和高度保存下来;
    2. 当没有更高的建筑时,依次将最高的建筑删除,将删除的建筑的R坐标和当前最高的建筑的高度保存下来;

    如何知道没有最高的建筑呢?

    1. 当所有的建筑都入队时,说明没有更高的了;
    2. 当一批连在一起的建筑群都检测完毕了,也可以开始进入下降趋势;

    因为每次要保证能访问到最高的建筑,所以使用了优先队列,以高度为优先级。

    vector<pair<int, int>> LeetCode::getSkyline(vector<vector<int>>& buildings){
        vector<pair<int,int>>skyLines;
        if (!buildings.size())return skyLines;
        //cur_X 表示横坐标可能是左边也可能是右边
        int cur = 0, cur_X, cur_H = -1, len = buildings.size();
        //优先队列按照高度大小优先度从高往低
        priority_queue< pair<int, int>> PQ; // first: height; second: 右边的横坐标R
        while (cur<len || !PQ.empty()){
            cur_X = PQ.empty() ? buildings[cur][0] : PQ.top().second;//获取队列头部最大高度的建筑的R坐标
    
            //下降趋势,cur不变,队列一直倒空,然后重新进入上升趋势(还有坐标)
            if (cur >= len || buildings[cur][0] > cur_X){//如果所有都入队,或者两批建筑未连在一起,中间不重合
                //说明上升的所有坐标都找到了,将最大高度的坐标出队,则第二高的建筑会到顶部
                while (!PQ.empty() && (PQ.top().second <= cur_X)) PQ.pop();
            }
            else{//上升趋势
                cur_X = buildings[cur][0];//获取当前的L坐标
                while (cur<len && buildings[cur][0] == cur_X){//可能会有与当前L坐标相同的多个建筑,都入队
                    PQ.push(make_pair(buildings[cur][2], buildings[cur][1]));
                    cur++;
                }
            }
            cur_H = PQ.empty() ? 0 : PQ.top().first;//比较看是否有新的更大的坐标;
            //上升趋势中,递增的当前最大高度与其对应的L坐标会入队;下降趋势中,前一个的最大高度的R坐标和当前的最大高度(前一个中第二高)入队
            if (skyLines.empty() || (skyLines.back().second != cur_H)) skyLines.push_back(make_pair(cur_X, cur_H));
        }
        return skyLines;
    }
  • 相关阅读:
    网站SEO关键词优化技巧
    SEO操作流程及网站优化技巧
    Linux服务器工作常用命令总结
    【转载】Linux常用命令大全(非常全!!!)
    myBatis出现Mapped Statements collection already contains value for
    maven打成war包之后没有class文件
    查询每个类型最新的一条记录
    关于 MySQL 的 boolean 和 tinyint(1) (转)
    Mac下的eclipse按住ctrl点击无法查看类文件
    Mac 10.10下安装MySQL5.6.21提示安装失败
  • 原文地址:https://www.cnblogs.com/yeqluofwupheng/p/6801525.html
Copyright © 2020-2023  润新知