Open In App
Related Articles

# The Skyline Problem using Divide and Conquer algorithm

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 a side and remove all sections that are not visible.  All buildings share common bottom and every building is represented by triplet (left, ht, right)

• ‘left’: is x coordinated of left side (or wall).
• ‘right’: is x coordinate of right side
• ‘ht’: is height of 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 left side of strip and ht is height of strip. Examples:

```Input: Array of 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: Skyline (an array of rectangular strips)
A strip has x coordinate of left side and height
(1, 11), (3, 13), (9, 0), (12, 7), (16, 3), (19, 18),
(22, 3), (25, 0)
Below image is for input 1 :```
```Consider following as another example when there is only one
building
Input:  {(1, 11, 5)}
Output: (1, 11), (5, 0)```

A Simple Solution is to initialize skyline or result as empty, then one by one add buildings to skyline. A building is added by first finding the overlapping strip(s). If there are no overlapping strips, the new building adds new strip(s). If overlapping strip is found, then height of the existing strip may increase. Time complexity of this solution is O(n2) We can find Skyline in Θ(nLogn) time using Divide and Conquer. The idea is similar to Merge Sort, divide the given set of buildings in two subsets. Recursively construct skyline for two halves and finally merge the two skylines. How to Merge two Skylines? The idea is similar to merge of merge sort, start from first strips of two skylines, compare x coordinates. Pick the strip with smaller x coordinate and add it to result. The height of added strip is considered as maximum of current heights from skyline1 and skyline2. Example to show working of merge:

```  Height of new Strip is always obtained by takin maximum of following
(a) Current height from skyline1, say 'h1'.
(b) Current height from skyline2, say 'h2'
h1 and h2 are initialized as 0. h1 is updated when a strip from
SkyLine1 is added to result and h2 is updated when a strip from

Skyline1 = {(1, 11),  (3, 13),  (9, 0),  (12, 7),  (16, 0)}
Skyline2 = {(14, 3),  (19, 18), (22, 3), (23, 13),  (29, 0)}
Result = {}
h1 = 0, h2 = 0

Compare (1, 11) and (14, 3).  Since first strip has smaller left x,
add it to result and increment index for Skyline1.
h1 = 11, New Height  = max(11, 0)
Result =   {(1, 11)}

Compare (3, 13) and (14, 3). Since first strip has smaller left x,
add it to result and increment index for Skyline1
h1 = 13, New Height =  max(13, 0)
Result =  {(1, 11), (3, 13)}

Similarly (9, 0) and (12, 7) are added.
h1 = 7, New Height =  max(7, 0) = 7
Result =   {(1, 11), (3, 13), (9, 0), (12, 7)}

Compare (16, 0) and (14, 3). Since second strip has smaller left x,
h2 = 3, New Height =  max(7, 3) = 7
Result =   {(1, 11), (3, 13), (9, 0), (12, 7), (14, 7)}

Compare (16, 0) and (19, 18). Since first strip has smaller left x,
h1 = 0, New Height =  max(0, 3) = 3
Result =   {(1, 11), (3, 13), (9, 0), (12, 7), (14, 7), (16, 3)}

Since Skyline1 has no more items, all remaining items of Skyline2
Result =   {(1, 11), (3, 13), (9, 0), (12, 7), (14, 7), (16, 3),
(19, 18), (22, 3), (23, 13), (29, 0)}

One observation about above output is, the strip (14, 7) is redundant
(There is already an strip of same height). We remove all redundant
strips.
Result =   {(1, 11), (3, 13), (9, 0), (12, 7), (16, 3), (19, 18),
(22, 3), (23, 13), (29, 0)}

In below code, redundancy is handled by not appending a strip if the
previous strip in result has same height.```

Below is C++ implementation of above idea.

## C++

 `// A divide and conquer based C++``// program to find skyline of given buildings``#include ``using` `namespace` `std;` `// A structure for building``struct` `Building {``    ``// x coordinate of left side``    ``int` `left;` `    ``// height``    ``int` `ht;` `    ``// x coordinate of right side``    ``int` `right;``};` `// A strip in skyline``class` `Strip {``    ``// x coordinate of left side``    ``int` `left;` `    ``// height``    ``int` `ht;` `public``:``    ``Strip(``int` `l = 0, ``int` `h = 0)``    ``{``        ``left = l;``        ``ht = h;``    ``}``    ``friend` `class` `SkyLine;``};` `// Skyline: To represent Output(An array of strips)``class` `SkyLine {``    ``// Array of strips``    ``Strip* arr;` `    ``// Capacity of strip array``    ``int` `capacity;` `    ``// Actual number of strips in array``    ``int` `n;` `public``:``    ``~SkyLine() { ``delete``[] arr; }``    ``int` `count() { ``return` `n; }` `    ``// A function to merge another skyline``    ``// to this skyline``    ``SkyLine* Merge(SkyLine* other);` `    ``// Constructor``    ``SkyLine(``int` `cap)``    ``{``        ``capacity = cap;``        ``arr = ``new` `Strip[cap];``        ``n = 0;``    ``}` `    ``// Function to add a strip 'st' to array``    ``void` `append(Strip* st)``    ``{``        ``// Check for redundant strip, a strip is``        ``// redundant if it has same height or left as previous``        ``if` `(n > 0 && arr[n - 1].ht == st->ht)``            ``return``;``        ``if` `(n > 0 && arr[n - 1].left == st->left) {``            ``arr[n - 1].ht = max(arr[n - 1].ht, st->ht);``            ``return``;``        ``}` `        ``arr[n] = *st;``        ``n++;``    ``}` `    ``// A utility function to print all strips of``    ``// skyline``    ``void` `print()``    ``{``        ``for` `(``int` `i = 0; i < n; i++) {``            ``cout << ``" ("` `<< arr[i].left << ``", "``                ``<< arr[i].ht << ``"), "``;``        ``}``    ``}``};` `// This function returns skyline for a``// given array of buildings arr[l..h].``// This function is similar to mergeSort().``SkyLine* findSkyline(Building arr[], ``int` `l, ``int` `h)``{``    ``if` `(l == h) {``        ``SkyLine* res = ``new` `SkyLine(2);``        ``res->append(``            ``new` `Strip(``                ``arr[l].left, arr[l].ht));``        ``res->append(``            ``new` `Strip(``                ``arr[l].right, 0));``        ``return` `res;``    ``}` `    ``int` `mid = (l + h) / 2;` `    ``// Recur for left and right halves``    ``// and merge the two results``    ``SkyLine* sl = findSkyline(``        ``arr, l, mid);``    ``SkyLine* sr = findSkyline(``        ``arr, mid + 1, h);``    ``SkyLine* res = sl->Merge(sr);` `    ``// To avoid memory leak``    ``delete` `sl;``    ``delete` `sr;` `    ``// Return merged skyline``    ``return` `res;``}` `// Similar to merge() in MergeSort``// This function merges another skyline``// 'other' to the skyline for which it is called.``// The function returns pointer to the``// resultant skyline``SkyLine* SkyLine::Merge(SkyLine* other)``{``    ``// Create a resultant skyline with``    ``// capacity as sum of two skylines``    ``SkyLine* res = ``new` `SkyLine(``        ``this``->n + other->n);` `    ``// To store current heights of two skylines``    ``int` `h1 = 0, h2 = 0;` `    ``// Indexes of strips in two skylines``    ``int` `i = 0, j = 0;``    ``while` `(i < ``this``->n && j < other->n) {``        ``// Compare x coordinates of left sides of two``        ``// skylines and put the smaller one in result``        ``if` `(``this``->arr[i].left < other->arr[j].left) {``            ``int` `x1 = ``this``->arr[i].left;``            ``h1 = ``this``->arr[i].ht;` `            ``// Choose height as max of two heights``            ``int` `maxh = max(h1, h2);` `            ``res->append(``new` `Strip(x1, maxh));``            ``i++;``        ``}``        ``else` `{``            ``int` `x2 = other->arr[j].left;``            ``h2 = other->arr[j].ht;``            ``int` `maxh = max(h1, h2);``            ``res->append(``new` `Strip(x2, maxh));``            ``j++;``        ``}``    ``}` `    ``// If there are strips left in this``    ``// skyline or other skyline``    ``while` `(i < ``this``->n) {``        ``res->append(&arr[i]);``        ``i++;``    ``}``    ``while` `(j < other->n) {``        ``res->append(&other->arr[j]);``        ``j++;``    ``}``    ``return` `res;``}` `// Driver Function``int` `main()``{``    ``Building arr[] = {``        ``{ 1, 11, 5 }, { 2, 6, 7 }, { 3, 13, 9 }, { 12, 7, 16 }, { 14, 3, 25 }, { 19, 18, 22 }, { 23, 13, 29 }, { 24, 4, 28 }``    ``};``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// Find skyline for given buildings``    ``// and print the skyline``    ``SkyLine* ptr = findSkyline(arr, 0, n - 1);``    ``cout << ``" Skyline for given buildings is \n"``;``    ``ptr->print();``    ``return` `0;``}`

## Java

 `// A divide and conquer based Java``// program to find skyline of given buildings``import` `java.util.*;``// A class for building``class` `Building {``    ``int` `left, ht, right;` `    ``public` `Building(``int` `left, ``int` `ht, ``int` `right) {``        ``this``.left = left;``        ``this``.ht = ht;``        ``this``.right = right;``    ``}``}``// A strip in skyline``class` `Strip {``    ``int` `left, ht;` `    ``public` `Strip(``int` `left, ``int` `ht) {``        ``this``.left = left;``        ``this``.ht = ht;``    ``}``}``// Skyline: To represent Output(An array of strips)``class` `SkyLine {``    ``List arr;``    ``int` `capacity, n;` `    ``public` `SkyLine(``int` `cap) {``        ``this``.arr = ``new` `ArrayList<>();``        ``this``.capacity = cap;``        ``this``.n = ``0``;``    ``}` `    ``public` `int` `count() {``        ``return` `this``.n;``    ``}` `// A function to merge another skyline``    ``// to this skyline`` ` `    ``public` `SkyLine merge(SkyLine other) {``        ``SkyLine res = ``new` `SkyLine(``this``.n + other.n);``        ``int` `h1 = ``0``, h2 = ``0``, i = ``0``, j = ``0``;``        ``while` `(i < ``this``.n && j < other.n) {``            ``if` `(``this``.arr.get(i).left < other.arr.get(j).left) {``                ``int` `x1 = ``this``.arr.get(i).left;``                ``h1 = ``this``.arr.get(i).ht;``                ``int` `maxh = Math.max(h1, h2);``                ``res.append(``new` `Strip(x1, maxh));``                ``i++;``            ``} ``else` `{``                ``int` `x2 = other.arr.get(j).left;``                ``h2 = other.arr.get(j).ht;``                ``int` `maxh = Math.max(h1, h2);``                ``res.append(``new` `Strip(x2, maxh));``                ``j++;``            ``}``        ``}``        ``while` `(i < ``this``.n) {``            ``res.append(``this``.arr.get(i));``            ``i++;``        ``}``        ``while` `(j < other.n) {``            ``res.append(other.arr.get(j));``            ``j++;``        ``}``        ``return` `res;``    ``}` `  ``// Function to add a strip 'st' to array``    ``public` `void` `append(Strip st) {``        ``if` `(``this``.n > ``0` `&& ``this``.arr.get(``this``.n-``1``).ht == st.ht) {``            ``return``;``        ``}``        ``if` `(``this``.n > ``0` `&& ``this``.arr.get(``this``.n-``1``).left == st.left) {``            ``this``.arr.get(``this``.n-``1``).ht = Math.max(``this``.arr.get(``this``.n-``1``).ht, st.ht);``            ``return``;``        ``}``        ``this``.arr.add(st);``        ``this``.n++;``    ``}` `   ``// A utility function to print all strips of``    ``// skyline``    ``public` `void` `printSkyline() {``        ``System.out.println(``"Skyline for given buildings is:"``);``        ``for` `(``int` `i = ``0``; i < ``this``.n; i++) {``            ``System.out.print(``"("` `+ ``this``.arr.get(i).left + ``", "` `+ ``this``.arr.get(i).ht + ``"), "``);``        ``}``        ``System.out.println();``    ``}``}` `// This function returns skyline for a``// given array of buildings arr[l..h].``// This function is similar to mergeSort().``class` `SkylineProblem {``    ``public` `static` `SkyLine findSkyline(Building[] arr, ``int` `l, ``int` `h) {``        ``if` `(l == h) {``            ``SkyLine res = ``new` `SkyLine(``2``);``            ``res.append(``new` `Strip(arr[l].left, arr[l].ht));``            ``res.append(``new` `Strip(arr[l].right, ``0``));``            ``return` `res;``        ``}``        ``int` `mid = (l + h) / ``2``;``        ` `        ` `    ``// Recur for left and right halves``    ``// and merge the two results``        ``SkyLine sl = findSkyline(arr, l, mid);``        ``SkyLine sr = findSkyline(arr, mid+``1``, h);``        ``SkyLine res = sl.merge(sr);``        ``return` `res;``    ``}``    ` `// Driver Code``public` `static` `void` `main(String[] args) {``    ` `Building[] arr = {``new` `Building(``1``, ``11``, ``5``), ``new` `Building(``2``, ``6``, ``7``), ``new` `Building(``3``, ``13``, ``9``),``new` `Building(``12``, ``7``, ``16``), ``new` `Building(``14``, ``3``, ``25``), ``new` `Building(``19``, ``18``, ``22``),``new` `Building(``23``, ``13``, ``29``), ``new` `Building(``24``, ``4``, ``28``)};` ` ``// Find skyline for given buildings``    ``// and print the skyline``SkyLine res = findSkyline(arr, ``0``, arr.length-``1``);``res.printSkyline();``}``}` `/* Output:``Skyline for given buildings is:``(1, 11), (3, 13), (9, 0), (12, 18), (22, 3), (25, 0), (28, 4), (29, 0),``*/`

## Python3

 `class` `Building:``    ``def` `__init__(``self``, left, ht, right):``        ``self``.left ``=` `left``        ``self``.ht ``=` `ht``        ``self``.right ``=` `right` `class` `Strip:``    ``def` `__init__(``self``, left``=``0``, ht``=``0``):``        ``self``.left ``=` `left``        ``self``.ht ``=` `ht` `class` `SkyLine:``    ``def` `__init__(``self``, cap):``        ``self``.arr ``=` `[]``        ``self``.capacity ``=` `cap``        ``self``.n ``=` `0` `    ``def` `count(``self``):``        ``return` `self``.n` `    ``def` `merge(``self``, other):``        ``res ``=` `SkyLine(``self``.n ``+` `other.n)``        ``h1, h2, i, j ``=` `0``, ``0``, ``0``, ``0``        ``while` `i < ``self``.n ``and` `j < other.n:``            ``if` `self``.arr[i].left < other.arr[j].left:``                ``x1, h1 ``=` `self``.arr[i].left, ``self``.arr[i].ht``                ``maxh ``=` `max``(h1, h2)``                ``res.append(Strip(x1, maxh))``                ``i ``+``=` `1``            ``else``:``                ``x2, h2 ``=` `other.arr[j].left, other.arr[j].ht``                ``maxh ``=` `max``(h1, h2)``                ``res.append(Strip(x2, maxh))``                ``j ``+``=` `1``        ``while` `i < ``self``.n:``            ``res.append(``self``.arr[i])``            ``i ``+``=` `1``        ``while` `j < other.n:``            ``res.append(other.arr[j])``            ``j ``+``=` `1``        ``return` `res` `    ``def` `append(``self``, st):``        ``if` `self``.n > ``0` `and` `self``.arr[``self``.n``-``1``].ht ``=``=` `st.ht:``            ``return``        ``if` `self``.n > ``0` `and` `self``.arr[``self``.n``-``1``].left ``=``=` `st.left:``            ``self``.arr[``self``.n``-``1``].ht ``=` `max``(``self``.arr[``self``.n``-``1``].ht, st.ht)``            ``return``        ``self``.arr.append(st)``        ``self``.n ``+``=` `1` `    ``def` `print_skyline(``self``):``        ``print``(``"Skyline for given buildings is"``)``        ``for` `i ``in` `range``(``self``.n):``            ``print``(``" ({}, {}),"``.``format``(``self``.arr[i].left, ``self``.arr[i].ht), end``=``"")``        ``print``()` `def` `find_skyline(arr, l, h):``    ``if` `l ``=``=` `h:``        ``res ``=` `SkyLine(``2``)``        ``res.append(Strip(arr[l].left, arr[l].ht))``        ``res.append(Strip(arr[l].right, ``0``))``        ``return` `res``    ``mid ``=` `(l ``+` `h) ``/``/` `2``    ``sl ``=` `find_skyline(arr, l, mid)``    ``sr ``=` `find_skyline(arr, mid``+``1``, h)``    ``res ``=` `sl.merge(sr)``    ``return` `res` `arr ``=` `[Building(``1``, ``11``, ``5``), Building(``2``, ``6``, ``7``), Building(``3``, ``13``, ``9``), Building(``12``, ``7``, ``16``), Building(``14``, ``3``, ``25``), Building(``19``, ``18``, ``22``), Building(``23``, ``13``, ``29``), Building(``24``, ``4``, ``28``)]``n ``=` `len``(arr)``skyline ``=` `find_skyline(arr, ``0``, n``-``1``)``skyline.print_skyline()`

## C#

 `// A divide and conquer based Java``// program to find skyline of given buildings``using` `System;``using` `System.Collections.Generic;` `// A class for building``public` `class` `Building {``    ``public` `int` `left, ht, right;` `    ``public` `Building(``int` `left, ``int` `ht, ``int` `right) {``        ``this``.left = left;``        ``this``.ht = ht;``        ``this``.right = right;``    ``}``}` `// A strip in skyline``public` `class` `Strip {``    ``public` `int` `left, ht;` `    ``public` `Strip(``int` `left, ``int` `ht) {``        ``this``.left = left;``        ``this``.ht = ht;``    ``}``}` `// Skyline: To represent Output(An array of strips)``public` `class` `SkyLine {``    ``public` `List arr;``    ``public` `int` `capacity, n;` `    ``public` `SkyLine(``int` `cap) {``        ``this``.arr = ``new` `List();``        ``this``.capacity = cap;``        ``this``.n = 0;``    ``}` `    ``public` `int` `count() {``        ``return` `this``.n;``    ``}` `// A function to merge another skyline``    ``// to this skyline``    ``public` `SkyLine merge(SkyLine other) {``        ``SkyLine res = ``new` `SkyLine(``this``.n + other.n);``        ``int` `h1 = 0, h2 = 0, i = 0, j = 0;``        ``while` `(i < ``this``.n && j < other.n) {``            ``if` `(``this``.arr[i].left < other.arr[j].left) {``                ``int` `x1 = ``this``.arr[i].left;``                ``h1 = ``this``.arr[i].ht;``                ``int` `maxh = Math.Max(h1, h2);``                ``res.append(``new` `Strip(x1, maxh));``                ``i++;``            ``} ``else` `{``                ``int` `x2 = other.arr[j].left;``                ``h2 = other.arr[j].ht;``                ``int` `maxh = Math.Max(h1, h2);``                ``res.append(``new` `Strip(x2, maxh));``                ``j++;``            ``}``        ``}``        ``while` `(i < ``this``.n) {``            ``res.append(``this``.arr[i]);``            ``i++;``        ``}``        ``while` `(j < other.n) {``            ``res.append(other.arr[j]);``            ``j++;``        ``}``        ``return` `res;``    ``}` `  ``// Function to add a strip 'st' to array``    ``public` `void` `append(Strip st) {``        ``if` `(``this``.n > 0 && ``this``.arr[``this``.n-1].ht == st.ht) {``            ``return``;``        ``}``        ``if` `(``this``.n > 0 && ``this``.arr[``this``.n-1].left == st.left) {``            ``this``.arr[``this``.n-1].ht = Math.Max(``this``.arr[``this``.n-1].ht, st.ht);``            ``return``;``        ``}``        ``this``.arr.Add(st);``        ``this``.n++;``    ``}` ` ``// A utility function to print all strips of``    ``// skyline``    ``public` `void` `printSkyline() {``        ``Console.WriteLine(``"Skyline for given buildings is:"``);``        ``for` `(``int` `i = 0; i < ``this``.n; i++) {``            ``Console.Write(``"("` `+ ``this``.arr[i].left + ``", "` `+ ``this``.arr[i].ht + ``"), "``);``        ``}``        ``Console.WriteLine();``    ``}``}` `// This function returns skyline for a``// given array of buildings arr[l..h].``// This function is similar to mergeSort().``public` `class` `SkylineProblem {``    ``public` `static` `SkyLine findSkyline(Building[] arr, ``int` `l, ``int` `h) {``        ``if` `(l == h) {``            ``SkyLine res2 = ``new` `SkyLine(2);``            ``res2.append(``new` `Strip(arr[l].left, arr[l].ht));``            ``res2.append(``new` `Strip(arr[l].right, 0));``            ``return` `res2;``        ``}``        ``int` `mid = (l + h) / 2;``        ` `      ``// Recur for left and right halves``      ``// and merge the two results``        ``SkyLine sl = findSkyline(arr, l, mid);``        ``SkyLine sr = findSkyline(arr, mid+1, h);``        ``SkyLine res3 = sl.merge(sr);``        ``return` `res3;``    ``}``    ` `// Driver Code``    ``public` `static` `void` `Main(``string``[] args) {``     ``Building[] arr = {``new` `Building(1, 11, 5), ``new` `Building(2, 6, 7), ``new` `Building(3, 13, 9),``     ``new` `Building(12, 7, 16), ``new` `Building(14, 3, 25), ``new` `Building(19, 18, 22),``      ``new` `Building(23, 13, 29), ``new` `Building(24, 4, 28)};` `    ``// Find skyline for given buildings and print the skyline``    ``SkyLine res1 = findSkyline(arr, 0, arr.Length-1);``    ``res1.printSkyline();``}``}`

## Javascript

 `// Js program to find skyline of given buildings` `// A structure for building``const Building = {``    ``left: Number,``    ``ht: Number,``    ``right: Number,``};` `class Strip {``    ``constructor(l = 0, h = 0) {``        ``this``.left = l;``        ``this``.ht = h;``    ``}``}` `class SkyLine {``    ``constructor(cap) {``        ``this``.capacity = cap;``        ``this``.arr = ``new` `Array(cap);``        ``this``.n = 0;``    ``}``    ``count() {``        ``return` `this``.n;``    ``}``    ``Merge(other) {``        ``let res = ``new` `SkyLine(``this``.n + other.n);``        ``let h1 = 0, h2 = 0;``        ``let i = 0, j = 0;``        ``// Merge two skylines by comparing the left coordinates of the strips``        ``while` `(i < ``this``.n && j < other.n) {``            ``if` `(``this``.arr[i].left < other.arr[j].left) {``                ``let x1 = ``this``.arr[i].left;``                ``h1 = ``this``.arr[i].ht;``                ``let maxh = Math.max(h1, h2);``                ``res.append(``new` `Strip(x1, maxh));``                ``i++;``            ``} ``else` `{``                ``let x2 = other.arr[j].left;``                ``h2 = other.arr[j].ht;``                ``let maxh = Math.max(h1, h2);``                ``res.append(``new` `Strip(x2, maxh));``                ``j++;``            ``}``        ``}``        ``// Append remaining strips from skyline 1 and 2``        ``while` `(i < ``this``.n) {``            ``res.append(``this``.arr[i]);``            ``i++;``        ``}``        ``while` `(j < other.n) {``            ``res.append(other.arr[j]);``            ``j++;``        ``}``        ``return` `res;``    ``}``    ``// Append a strip to skyline if it is not redundant``    ``append(st) {``        ``if` `(``this``.n > 0 && ``this``.arr[``this``.n - 1].ht == st.ht) {``            ``return``;``        ``}``        ``if` `(``this``.n > 0 && ``this``.arr[``this``.n - 1].left == st.left) {``            ``this``.arr[``this``.n - 1].ht = Math.max(``this``.arr[``this``.n - 1].ht, st.ht);``            ``return``;``        ``}``        ``this``.arr[``this``.n] = st;``        ``this``.n++;``    ``}``    ``// Print the skyline strips``    ``print() {``        ``let str = ``''``;``        ``for` `(let i = 0; i < ``this``.n; i++) {``            ``str += `(\${``this``.arr[i].left}, \${``this``.arr[i].ht}), `;``        ``}``        ``console.log(`Skyline ``for` `given buildings is \n\${str}`);``    ``}``}` `function` `findSkyline(arr, l, h) {``    ``if` `(l == h) {``        ``// Base case: when a single building is left``        ``let res = ``new` `SkyLine(2);``        ``res.append(``new` `Strip(arr[l].left, arr[l].ht));``        ``res.append(``new` `Strip(arr[l].right, 0));``        ``return` `res;``    ``}``    ``// Divide and Conquer approach``    ``let mid = Math.floor((l + h) / 2);``    ``let sl = findSkyline(arr, l, mid);``    ``let sr = findSkyline(arr, mid + 1, h);``    ``let res = sl.Merge(sr);``    ``delete` `sl;``    ``delete` `sr;``    ``return` `res;``}` `const main = () => {``const arr = [``{ left: 1, ht: 11, right: 5 },``{ left: 2, ht: 6, right: 7 },``{ left: 3, ht: 13, right: 9 },``{ left: 12, ht: 7, right: 16 },``{ left: 14, ht: 3, right: 25 },``{ left: 19, ht: 18, right: 22 },``{ left: 23, ht: 13, right: 29 },``{ left: 24, ht: 4, right: 28 },``];``const n = arr.length;``const ptr = findSkyline(arr, 0, n - 1);``console.log(``"Skyline for given buildings is"``);``ptr.print();``};` `main();`

Output

``` Skyline for given buildings is
(1, 11),  (3, 13),  (9, 0),  (12, 7),  (16, 3),  (19, 18),  (22, 3),  (23, 13),  (29, 0), ```

Time complexity of above recursive implementation is same as Merge Sort. T(n) = T(n/2) + Θ(n) Solution of above recurrence is Θ(nLogn) References: