 GeeksforGeeks App
Open App Browser
Continue

## Related Articles

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:

1. From the given triplets for each building, retrieve the left wall location, height and right wall location value.
2. 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.
3. Sort the walls in ascending order.
4. 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.
5. 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.
6. 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 ``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];` `        ``// Get height of building``        ``height = buildings[i];` `        ``// Get right point of building``        ``right = buildings[i];` `        ``// 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<``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 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;` `    ``// 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;``}`

## Java

 `import` `java.util.*;` `public` `class` `Skyline {` `    ``public` `static` `List<``int``[]> createSkyline(``int``[][] buildings) {``        ``List<``int``[]> wall = ``new` `ArrayList<>();``        ``int` `N = buildings.length;``        ``int` `left, height, right;``        ``for` `(``int` `i = ``0``; i < N; i++) {``            ``left = buildings[i][``0``];``            ``height = buildings[i][``1``];``            ``right = buildings[i][``2``];``            ``wall.add(``new` `int``[]{left, -height});``            ``wall.add(``new` `int``[]{right, height});``        ``}``        ``wall.sort((a, b) -> a[``0``] != b[``0``] ? a[``0``] - b[``0``] : a[``1``] - b[``1``]);``        ``List<``int``[]> skyline = ``new` `ArrayList<>();``        ``TreeSet leftWallHeight = ``new` `TreeSet<>(Collections.singleton(``0``));``        ``int` `top = ``0``;``        ``for` `(``int``[] w : wall) {``            ``if` `(w[``1``] < ``0``) {``                ``leftWallHeight.add(-w[``1``]);``            ``} ``else` `{``                ``leftWallHeight.remove(w[``1``]);``            ``}``            ``int` `curTop = leftWallHeight.last();``            ``if` `(curTop != top) {``                ``top = curTop;``                ``skyline.add(``new` `int``[]{w[``0``], top});``            ``}``        ``}``        ``return` `skyline;``    ``}` `    ``public` `static` `void` `printSkyline(``int``[][] buildings) {``        ``List<``int``[]> skyline = createSkyline(buildings);``        ``System.out.println(``"Skyline for given buildings:"``);``        ``System.out.print(``"{"``);``        ``for` `(``int``[] it : skyline) {``            ``System.out.print(``"{"` `+ it[``0``] + ``", "` `+ it[``1``] + ``"} "``);``        ``}``        ``System.out.println(``"}"``);``    ``}` `    ``public` `static` `void` `main(String[] args) {``        ``int``[][] 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``}};``        ``printSkyline(buildings);``    ``}``}`

## Python3

 `# pyton equivalent code``from` `functools ``import` `cmp_to_key` `def` `func(a, b):``    ``if``(a[``0``] !``=` `b[``0``]):``        ``return` `a[``0``] ``-` `b[``0``]``    ``else``:``        ``return` `a[``1``] ``-` `b[``1``]``    ` `def` `createSkyline(buildings):``    ` `    ``wall ``=` `[]``    ``N ``=` `len``(buildings)``    ``left ``=` `0``    ``height ``=` `0``    ``right ``=` `0``    ``for` `i ``in` `range``(N):``        ``left ``=` `buildings[i][``0``]``        ``height ``=` `buildings[i][``1``]``        ``right ``=` `buildings[i][``2``]``        ``wall.append([left, ``-``height])``        ``wall.append([right, height])``    ` `    ``letter_cmp_key ``=` `cmp_to_key(func)``    ``wall.sort(key ``=` `letter_cmp_key)``    ``# wall.sort(func)` `    ``skyline ``=` `[]``    ``leftWallHeight ``=` `set``()``    ``leftWallHeight.add(``0``)``    ` `    ``top ``=` `0``    ``for` `w ``in` `wall:``        ``if` `w[``1``] < ``0``:``            ``leftWallHeight.add(``-``w[``1``])``        ``else``:``            ``leftWallHeight.remove(w[``1``])``            ` `        ``curTop ``=` `max``(leftWallHeight)``        ``if` `curTop !``=` `top:``            ``top ``=` `curTop;``            ``skyline.append([w[``0``], top])` `    ``return` `skyline` `def` `printSkyline(buildings):` `    ``skyline ``=` `createSkyline(buildings)``    ``print``(``'Skyline for given buildings:'``)``    ``temp ``=` `'{'``    ` `    ``for` `it ``in` `skyline:``        ``temp ``=` `temp ``+` `"{"` `+` `str``(it[``0``]) ``+` `","` `+` `str``(it[``1``]) ``+` `"} "` `    ``print``(temp ``+` `'}'``)`  `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``]]` `printSkyline(buildings)` `# The code is contributed by Nidhi goel.`

## Javascript

 `// Javascript equivalent code` `const createSkyline = (buildings) => {``    ``let wall = [];``    ``let N = buildings.length;``    ``let left, height, right;``    ``for` `(let i = 0; i < N; i++) {``        ``left = buildings[i];``        ``height = buildings[i];``        ``right = buildings[i];``        ``wall.push([left, -height]);``        ``wall.push([right, height]);``    ``}``    ``wall.sort((a, b) => {``        ``if` `(a !== b) {``            ``return` `a - b;``        ``} ``else` `{``            ``return` `a - b;``        ``}``    ``});``    ``let skyline = [];``    ``let leftWallHeight = ``new` `Set();``    ``let top = 0;``    ``for` `(let w of wall) {``        ``if` `(w < 0) {``            ``leftWallHeight.add(-w);``        ``} ``else` `{``            ``leftWallHeight.``delete``(w);``        ``}``        ``let curTop = Math.max(...leftWallHeight);``        ``if` `(curTop !== top) {``            ``top = curTop;``            ``skyline.push([w, top]);``        ``}``    ``}``    ``return` `skyline;``}` `const printSkyline = (buildings) => {``    ``let skyline = createSkyline(buildings);``    ``console.log(``'Skyline for given buildings:'``);``    ``temp = ``'{'``;``    ``for` `(let it of skyline) {``       ``temp = temp +`{\${it}, \${it}} `;``    ``}``    ``console.log(temp + ``'}'``);``}` `let 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]];` `printSkyline(buildings);`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;``using` `System.Linq;` `class` `Program``{``    ``static` `int` `func(``int``[] a, ``int``[] b)``    ``{``        ``if` `(a != b)``        ``{``            ``return` `a - b;``        ``}``        ``else``        ``{``            ``return` `a - b;``        ``}``    ``}` `    ``static` `List<``int``[]> createSkyline(List<``int``[]> buildings)``    ``{``        ``List<``int``[]> wall = ``new` `List<``int``[]>();``        ``int` `N = buildings.Count;``        ``int` `left = 0;``        ``int` `height = 0;``        ``int` `right = 0;``        ``for` `(``int` `i = 0; i < N; i++)``        ``{``            ``left = buildings[i];``            ``height = buildings[i];``            ``right = buildings[i];``            ``wall.Add(``new` `int``[] { left, -height });``            ``wall.Add(``new` `int``[] { right, height });``        ``}` `        ``Comparison<``int``[]> letter_cmp_key = ``new` `Comparison<``int``[]>(func);``        ``wall.Sort(letter_cmp_key);` `        ``List<``int``[]> skyline = ``new` `List<``int``[]>();``        ``SortedSet<``int``> leftWallHeight = ``new` `SortedSet<``int``>();``        ``leftWallHeight.Add(0);` `        ``int` `top = 0;``        ``foreach` `(``int``[] w ``in` `wall)``        ``{``            ``if` `(w < 0)``            ``{``                ``leftWallHeight.Add(-w);``            ``}``            ``else``            ``{``                ``leftWallHeight.Remove(w);``            ``}` `            ``int` `curTop = leftWallHeight.Max;``            ``if` `(curTop != top)``            ``{``                ``top = curTop;``                ``skyline.Add(``new` `int``[] { w, top });``            ``}``        ``}` `        ``return` `skyline;``    ``}` `    ``static` `void` `printSkyline(List<``int``[]> buildings)``    ``{``        ``List<``int``[]> skyline = createSkyline(buildings);``        ``Console.WriteLine(``"Skyline for given buildings:"``);``        ``string` `temp = ``"{"``;` `        ``foreach` `(``int``[] it ``in` `skyline)``        ``{``            ``temp = temp + ``"{"` `+ it + ``","` `+ it + ``"} "``;``        ``}` `        ``Console.WriteLine(temp + ``"}"``);``    ``}` `    ``static` `void` `Main(``string``[] args)``    ``{``        ``List<``int``[]> buildings = ``new` `List<``int``[]> {``            ``new` `int``[] {1, 11, 5},``            ``new` `int``[] {2, 6, 7},``            ``new` `int``[] {3, 13, 9},``            ``new` `int``[] {12, 7, 16},``            ``new` `int``[] {14, 3, 25},``            ``new` `int``[] {19, 18, 22},``            ``new` `int``[] {23, 13, 29},``            ``new` `int``[] {24, 4, 28}``        ``};` `        ``printSkyline(buildings);` `         ` `    ``}``}``// The code is contributed by shivamsharma215.`

Output

```Skyline for given buildings:
{{1, 11} {3, 13} {9, 0} {12, 7} {16, 3} {19, 18} {22, 3} {23, 13} {29, 0} }```

Another Approach:

## Python3

 `import` `heapq``def` `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))`

Output

`[[1, 11], [3, 13], [9, 0], [12, 7], [16, 3], [19, 18], [22, 3], [23, 13], [29, 0]]`

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up