给定二维城市中的 n 个矩形建筑物,计算这些建筑物的天际线,消除隐藏线。主要任务是从侧面查看建筑物并删除所有不可见的部分。
所有建筑物共用一个底部,每个建筑物都由一个三元组(左,ht,右)表示
- left: x 坐标在左侧(或墙壁)。
- right:是右侧的 x 坐标。
- ht:是建筑物的高度。
天际线是矩形条带的集合。矩形条带表示为一对 (left, ht),其中 left 是条带左侧的 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} }
方法:
- 从每个建筑物的给定三元组中,检索左墙位置、高度和右墙位置值。
- 将具有负高度值的左墙和具有实际高度的右墙作为一对存储在向量wall 中。这样做是为了区分同一建筑物的左墙和右墙。
- 按升序对墙壁进行排序。
- 遍历向量walls ,如果找到左墙,则将左墙的高度存储在multiset M中。否则,如果遇到右墙,则从multiset中移除其对应的高度。
- 检查最高值是否已更改。如果它已更改,则更新顶部值并将当前墙的 abscissa(x-cordinate) 值和更新后的顶部值存储在向量中作为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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live