给定一个二维城市中的n座矩形建筑物,可以计算这些建筑物的天际线,从而消除隐藏线。主要任务是从一边查看建筑物,然后删除所有不可见的部分。
所有建筑物都具有共同的底部,并且每栋建筑物都由一个三元组表示(左,ht,右)
- 左:在左侧(或墙壁)上x坐标。
- 右:是右侧的x坐标。
- ht:是建筑物的高度。
天际线是矩形带的集合。矩形带表示为一对(左,ht),其中,左是带左侧的x坐标,而ht是带的高度。
例子:
Input: buildings[][] = { {1, 11, 5}, {2, 6, 7}, {3, 13, 9}, {12, 7, 16}, {14, 3, 25}, {19, 18, 22}, {23, 13, 29}, {24, 4, 28} }
Output: { {1, 11}, {3, 13}, {9, 0}, {12, 7}, {16, 3}, {19, 18}, {22, 3}, {23, 13}, {29, 0} }
Explanation:
The skyline is formed based on the key-points (representing by “green” dots)
eliminating hidden walls of the buildings.
Input: buildings[ ][ ] = { {1, 11, 5} }
Output: { {1, 11}, {5, 0} }
方法:
- 从每个建筑物的给定三元组中,检索左墙位置,高度和右墙位置值。
- 将左墙的负高度值和右墙的实际高度成对存储在向量墙中。这样做是为了区分同一建筑物的左墙和右墙。
- 按升序对墙壁进行排序。
- 遍历矢量墙(如果找到了左墙),则将左墙的高度存储在多重集M中。否则,如果遇到右墙,则从多重集中删除其对应的高度。
- 检查最高值是否已更改。如果它已更改,则更新最高值,并将当前墙的横坐标(x坐标)值和更新的最高值存储在vector中,作为skyline 。
- 打印存储在天际线矢量中的值对。
下面是上述方法的实现:
C++
// C++ progrqam for the above approach
#include
using namespace std;
// Function to create skyline
vector >
createSkyline(vector >& buildings)
{
// Get the number of buildings
int N = buildings.size();
// To store the left and right
// wall position of the buildings
vector > wall;
// Triplet of building structure
// parameters
int left, height, right;
for (int i = 0; i < N; i++) {
// Get left point of building
left = buildings[i][0];
// Get height of building
height = buildings[i][1];
// Get right point of building
right = buildings[i][2];
// Store left point and height
// of the left wall
// Negative value means left wall
// will be inserted to multiset first
// for the same abscissa(x) as right wall
wall.push_back({ left, -height });
// Store right point and height
// of the right wall
wall.push_back(
make_pair(right, height));
}
// Sort the walls in ascending order
sort(wall.begin(), wall.end());
// To store skyline: output
vector > skyline;
// Initialize a multiset to
// keep left wall heights sorted
multiset leftWallHeight = { 0 };
// Current max height among
// leftWallHeights
int top = 0;
// Traverse through the sorted walls
for (auto w : wall) {
// If left wall is found
if (w.second < 0) {
// Insert the height
leftWallHeight.insert(-w.second);
}
// If right wall is found
else {
// Remove the height
leftWallHeight.erase(
leftWallHeight.find(w.second));
}
// Mark a skyline point if top changes
// .rbegin(): reverse iterator
if (*leftWallHeight.rbegin() != top) {
top = *leftWallHeight.rbegin();
skyline.push_back(
make_pair(w.first, top));
}
}
// Return skyline to printSkyline
return skyline;
}
// Function to print the output skyline
void printSkyline(
vector >& buildings)
{
// Function call for creating skyline
vector > skyline
= createSkyline(buildings);
cout << "Skyline for given"
<< " buildings:\n{";
for (auto it : skyline) {
cout << "{" << it.first << ", "
<< it.second << "} ";
}
cout << "}";
}
// Driver Code
int main()
{
vector > buildings;blockquote
// Given left and right location
// and height of the wall
buildings = { { 1, 11, 5 }, { 2, 6, 7 },
{ 3, 13, 9 }, { 12, 7, 16 },
{ 14, 3, 25 }, { 19, 18, 22 },
{ 23, 13, 29 }, { 24, 4, 28 } };
// Function Call
printSkyline(buildings);
return 0;
}
Skyline for given buildings:
{{1, 11} {3, 13} {9, 0} {12, 7} {16, 3} {19, 18} {22, 3} {23, 13} {29, 0} }
时间复杂度: O(N * log(N))
辅助空间: O(N)