The Skyline Problem | Set 2

09 Feb, 2022
Given n rectangular buildings in a 2-dimensional city, computes the skyline of these buildings, eliminating hidden lines. The main task is to view buildings from aside and remove all sections that are not visible. 
All buildings share common bottom and every building is represented by a triplet (left, ht, right) 
left: is x coordinated on the left side (or wall).
right: is x coordinate of the right side.
ht: is the height of the building.
A skyline is a collection of rectangular strips. A rectangular strip is represented as a pair (left, ht) where left is x coordinate of the left side of strip and ht is the height of strip.
Examples: 
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} }
Approach: 
From the given triplets for each building, retrieve the left wall location, height and right wall location value.Store the left wall with its negative value of height and the right wall with its actual height as a pair in a vector walls. This is done in order to distinguish between left and right walls of the same building.Sort the walls in ascending order.Traverse the vector walls, if a left wall is found, store the height of the left wall in the multiset M. Otherwise, if a right wall is encountered, remove its corresponding height from the multiset.Check if the top value has changed or not. If it has changed, then update the top value and store the current wall’s abscissa(x-coordinate) value and the updated top value in a vector as skyline.Print the value pairs stored in the skyline vector.
From the given triplets for each building, retrieve the left wall location, height and right wall location value.
Store the left wall with its negative value of height and the right wall with its actual height as a pair in a vector walls. This is done in order to distinguish between left and right walls of the same building.
Sort the walls in ascending order.
Traverse the vector walls, if a left wall is found, store the height of the left wall in the multiset M. Otherwise, if a right wall is encountered, remove its corresponding height from the multiset.
Check if the top value has changed or not. If it has changed, then update the top value and store the current wall’s abscissa(x-coordinate) value and the updated top value in a vector as skyline.
Print the value pairs stored in the skyline vector.
Below is the implementation of 
the above approach: 
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Function to create skylinevector<pair<int, int> >createSkyline(vector<vector<int> >& buildings){     // Get the number of buildings    int N = buildings.size();     // To store the left and right    // wall position of the buildings    vector<pair<int, int> > 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<pair<int, int> > skyline;     // Initialize a multiset to    // keep left wall heights sorted    multiset<int> 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 skylinevoid printSkyline(    vector<vector<int> >& buildings){     // Function call for creating skyline    vector<pair<int, int> > skyline        = createSkyline(buildings);     cout << "Skyline for given"         << " buildings:\n{";     for (auto it : skyline) {         cout << "{" << it.first << ", "             << it.second << "} ";    }    cout << "}";} // Driver Codeint main(){    vector<vector<int> > buildings;     // 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;}
Another Approach:
Python3
import heapqdef getSkyline(buildings):      # Stores the building information in the following manner:[left,right,height]    buildings=list(map(lambda x: [x[0],x[2],x[1]],buildings))         buildings_start=[0] # priority queue    buildings_end=dict() #map         # Stores the position and height of the present building and whether it is the endpoint of a building    new_buildings=[]    for s,e,h in buildings:        new_buildings.append((s,h,False))        new_buildings.append((e,h,True))             # Sorting the buildings according to their position    new_buildings.sort(key= lambda x:(x[0],x[2]))         # Stores the answer    skyline=[]    for x,y,end in new_buildings:                   if not end:        # if it is the starting point of a building push it in the heap            if (not skyline) or y>skyline[-1][1]:                if skyline and x==skyline[-1][0]:                    skyline[-1][1]=y                else:                    skyline.append([x,y])                heapq.heappush(buildings_start,-y)            else:                heapq.heappush(buildings_start,-y)        else:        # if it is the ending point of a building            if y==skyline[-1][1]:                heapq.heappop(buildings_start)                if x==skyline[-1][0]:                    skyline.pop()                y=heapq.heappop(buildings_start)                while -y in buildings_end:                    buildings_end[-y]-=1                    if buildings_end[-y]==0:                        del(buildings_end[-y])                    y=heapq.heappop(buildings_start)                if -y!=skyline[-1][1]:                    skyline.append([x,-y])                heapq.heappush(buildings_start,y)            else:                buildings_end[y]=buildings_end.get(y,0)+1    return skyline if __name__ == '__main__':    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 ] ]    print(getSkyline(buildings))
Time Complexity: O(N * log(N)) Auxiliary Space: O(N) 
sagar0719kumar
ashutoshsinghgeeksforgeeks
amartyaghoshgfg
surinderdawra388
Algorithms
Competitive Programming
Data Structures
Sorting
Data Structures
Sorting
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
How to Start Learning DSA?
Complete Roadmap To Learn DSA From Scratch
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Competitive Programming - A Complete Guide
Practice for cracking any coding interview
Modulo 10^9+7 (1000000007)
Arrow operator -> in C/C++ with Examples
Prefix Sum Array - Implementation and Applications in Competitive Programming