[leetcode] 218.The Skyline Problem
2015-08-17 15:42
435 查看
题目:
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).
Buildings Skyline Contour
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_MAX, 0 < 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], …]
题意:
题目的意思是找出这些长方形的建筑的一些边际点。如图A,B所示,找的其实是沿着x轴从左往右扫描时出现的矩形最高点的开始位置(即矩形的右上角)。比如第一个位置是[2,10],这是整个图形的开始,所以该点是当前开始时的最高点。继续往后扫描到[3,15],接下来的长方形的高会变化到15,所以这个左上角的点也要保存。继续扫描下去,当x=7的时候,图形的高度会从当前的最高高度15降到次高高度12,所以将[7,12]这个作为接下来矩形的最大高度保存。当扫描到12时,前面一块的长方形已经全部结束。这个时候需要保存这个右下角的点即[12,0]。
思路:
从上面对题目的分析,我们可以看出,我们需要保存的是扫描到当前位置时,图形中的最高位置。如果遇到一个更高的位置,那么需要加入这个左上角的位置。如果从这个最高位置出来了,那么需要判断接下来图形的最高位置是什么,因为可能多个长方形都是一个高度,所以次高位置跟最高位置可能相同。使用堆来完成。我们可以使用STL中multimap来完成。
整个过程首先是将这些点按照x轴进行排列,然后依次扫描这些点。这些点需要区分为是矩形的左边的边还是右边的那条边。从而决定是将这个最大高度加入,还是将最高高度去除。
代码如下:
需要考虑的边际情况比较多。
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).
Buildings Skyline Contour
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_MAX, 0 < 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], …]
题意:
题目的意思是找出这些长方形的建筑的一些边际点。如图A,B所示,找的其实是沿着x轴从左往右扫描时出现的矩形最高点的开始位置(即矩形的右上角)。比如第一个位置是[2,10],这是整个图形的开始,所以该点是当前开始时的最高点。继续往后扫描到[3,15],接下来的长方形的高会变化到15,所以这个左上角的点也要保存。继续扫描下去,当x=7的时候,图形的高度会从当前的最高高度15降到次高高度12,所以将[7,12]这个作为接下来矩形的最大高度保存。当扫描到12时,前面一块的长方形已经全部结束。这个时候需要保存这个右下角的点即[12,0]。
思路:
从上面对题目的分析,我们可以看出,我们需要保存的是扫描到当前位置时,图形中的最高位置。如果遇到一个更高的位置,那么需要加入这个左上角的位置。如果从这个最高位置出来了,那么需要判断接下来图形的最高位置是什么,因为可能多个长方形都是一个高度,所以次高位置跟最高位置可能相同。使用堆来完成。我们可以使用STL中multimap来完成。
整个过程首先是将这些点按照x轴进行排列,然后依次扫描这些点。这些点需要区分为是矩形的左边的边还是右边的那条边。从而决定是将这个最大高度加入,还是将最高高度去除。
代码如下:
需要考虑的边际情况比较多。
struct myCompare { bool operator()(vector<int> a, vector<int> b) { return a[0] < b[0]; } }mycompare; struct keyComp { bool operator()(int a, int b) { return a > b; } }; class Solution { public: vector<pair<int, int>> getSkyline(vector<vector<int>>& buildings) { vector<pair<int, int>> result; if (buildings.empty())return result; vector<vector<int>> x_height; for (auto a : buildings) { vector<int> t1 = { a[0], a[2], 0 }; x_height.push_back(t1); vector<int> t2 = { a[1], a[2], 1 }; x_height.push_back(t2); } sort(x_height.begin(), x_height.end(), mycompare); multimap<int, int, keyComp> heights; int size = x_height.size(); int heights_size = 0; for (int i = 0; i < size; i++) { switch (x_height[i][2]) { case 0: { if (heights.empty() || x_height[i][1] > (heights.begin())->first) { if ((result.size() == 1 && x_height[i][0] == result.back().first && x_height[i][1] > result.back().second) || (result.size() > 1 && x_height[i][0] == result.back().first)) { result.pop_back(); if (result.empty() || (result.size() >= 1 && x_height[i][1] != result.back().second)) result.push_back(pair<int, int>(x_height[i][0], x_height[i][1])); } else if (result.empty() || (x_height[i][1] != result.back().second)) result.push_back(pair<int, int>(x_height[i][0], x_height[i][1])); } heights.insert(pair<int, int>(x_height[i][1], 1)); heights_size++; }break; case 1: { if (heights_size == 1) { if (x_height[i][0] == result.back().first)result.pop_back(); result.push_back(pair<int, int>(x_height[i][0], 0)); } else if (x_height[i][1] == (heights.begin())->first && (heights.begin())->first != (++heights.begin())->first) { if (result.empty() || (++heights.begin())->first != result.back().second){ if(!(!result.empty() && x_height[i][0] == (result.back().first))) result.push_back(pair<int, int>(x_height[i][0], (++heights.begin())->first)); } } heights.erase(heights.find(x_height[i][1])); heights_size--; }break; } } return result; } };
相关文章推荐
- 自定义控制器转场动画及实现下拉菜单的小Demo
- windows下oracle自动备份
- 阻尼滑动--可以滑动过度的ScrollView(OverScrollView)
- Delphi开发学习一:使用ADOConnection控件连接数据库SQL
- java简易图书管理之三层模式
- fir.im Weekly - 工欲善其事,必先利其器
- Jquery-DataTable 使用介绍
- 为OCR和Votingdisk准备rawdevices
- 如果让我重新设计一款Android App
- 漫话C++0x
- linux安装rzsz
- centos下oracle11g的安装与启动
- Android4.4 Wi-Fi P2P WifiP2pService中消息处理
- 【bzoj1059】 ZJOI2007矩阵游戏 二分图匹配
- Linux____文件的压缩与打包学习笔记
- Mac下一个svn提交.a文件
- java 和 C++ Socket通信(java作为服务端server,C++作为客户端client,解决中文乱码问题GBK和UTF8)
- 【2015-8-17】加载JAVA包过程
- 利用P3P实现跨域设置cookie
- MySQL调优