📜  天际线问题 | 2套

📅  最后修改于: 2021-09-07 05:06:44             🧑  作者: Mango

给定二维城市中的 n 个矩形建筑物,计算这些建筑物的天际线,消除隐藏线。主要任务是从侧面查看建筑物并删除所有不可见的部分。
所有建筑物共用一个底部,每个建筑物都由一个三元组(左,ht,右)表示

  • left: x 坐标在左侧(或墙壁)。
  • right:是右侧的 x 坐标。
  • ht:是建筑物的高度。

天际线是矩形条带的集合。矩形条带表示为一对 (left, ht),其中 left 是条带左侧的 x 坐标,ht 是条带的高度。

例子:

方法:

  1. 从每个建筑物的给定三元组中,检索左墙位置、高度和右墙位置值。
  2. 将具有负高度值的左墙和具有实际高度的右墙作为一对存储在向量wall 中。这样做是为了区分同一建筑物的左墙和右墙。
  3. 按升序对墙壁进行排序。
  4. 遍历向量walls ,如果找到左墙,则将左墙的高度存储在multiset M中。否则,如果遇到右墙,则从multiset中移除其对应的高度。
  5. 检查最高值是否已更改。如果它已更改,则更新顶部值并将当前墙的 abscissa(x-cordinate) 值和更新后的顶部值存储在向量中作为skyline
  6. 打印存储在天际线向量中的值对。

下面是上述方法的实现:

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;
}


输出:

时间复杂度: O(N * log(N))
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live