swezo1s Divide and Conquer | Set 7 (The Skyline Problem) - GeekstorGoeks
GeeksforGeeks
‘A computer science portal for geeks
Placements Practice GATECS IDE Q&A _ GeeksQuiz
[ Login/Register
Divide and Conquer | Set 7 (The Skyline Problem)
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 remave all sections that are not visible.
Al buildings share common bottom and every building is represented by triplet (left,
hit, right)
10)
‘left’: is x coordinated of left side (or wall)
‘right’: is x coordinate of right side
‘ht: Is height of building
For example, the building on right side (the figure is taken from here) is represented as
(1.11, 5) oS
‘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,139), (12,726), (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
(2, 11), (3, 13), (8, @), (22, 7), (16, 3), (29, 18),
(22, 3), (25, @)
The below figure (taken fron here) demonstrates input and output.
The left side shows buildings and right side shows skyline.
Consider following as another exanple when there is only one
building
ipl. geekslorgooks og vide-and-conquer-set7-he-skyline- problem wmswezo16 Divide and Conquer | Set 7 (The Skyline Problem) - GeekstorGoeks
Input: {(1, 11, 5))
output: (1, 11), (5, @)
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(n?)
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 skyline and skyline?
Example to show working of merge:
Height of new Strip is always obtained by takin maxinun of following
(a) Current height from skylinet, say "hi".
(b) Current height from skyline2, say *h2*
hi ang h2 are initialized as @. hi is updated when a strip from
SkyLinel is added to result and h2 is updated when a strip from
SkyLine2 is added.
Skylinet = ((2, 11), (3, 13), (9, 8), (12, 7), (16, @)}
Skyline2 = ((24, 3), (19, 18), (22, 3), (23, 13), (29, ®)}
Result = {)
m= 0, h2=0
Conpare (1, 11) and (14, 3). Since finst strip has smaller left x,
add it to result and increment index for Sky:
hi = 11, New Height = max(11, @)
Result = (1, 11))
Compare (3, 13) and (14, 3). Since first strip has smaller left x,
add it to result and increnent index for Skylinel
hi = 13, New Height = max(13, @)
Result = ((1, 12), (3, 13)}
Similarly (9, @) and (42, 7) are added.
hi = 7, New Height = nax(7, @) = 7
Result = ((2, 11), (3, 13), (9, 4), (12, 7)}
Compare (16, @) and (14, 3). Since second strip has smaller left x,
At is added to result.
h2 = 3, New Height = max(7, 3) =7
Result = {(2, 11), (3, 13), (9, @), (12, 7), (14, 7)}
Conpare (26, @) and (19, 18). Since first strip has smaller left x,
it is added to result.
hi = ®, New Height = max(@, 3) = 3
Result = (1, 11), (3, 13), (9, @), (12, 7), (14, 3), (16, 3)}
Since Skyline1 has no more items, all remaining itens of Skyline2
are added
Result = (1, 11), (3, 13), (9, 8), (22, 7), (14, 3), (48, 3),
ipl. geekslorgoeks og vide-and-conquer-set7-he-skyline-prablemy/ antswezo16 Divide and Conquer | Set 7 (The Skyline Problem) - GeekstorGoeks
(49, 18), (22, 3), (23, 13), (29, @))
ne observation about above output is, the strip (16, 3) is redundant
(There is already an strip of sane height). We renove ll redundant
strips.
Result = {(2, 11), (3, 13), (9, @), (12, 7), (14, 3), (29, 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 sane height.
Below is C++ implementation of above idea,
JJ A divide and conquer based C++ program to find skyline of given
71 buildings
#includeciostream>
using namespace std;
// A structure for building
struct Building
int left; // x coordinate of left side
int ht; ” // height
int right; // x coordinate of right side
b
JA strip in skyline
class Strip
int left; // x coordinate of left side
int ht; // height
public:
Strip(int 1-0, int he@)
{
left = 15
ht = hs
t
friend class SkyLine;
b
JJ Skyline: To represent Output (An array of strips)
class SkyLine
Strip tar; // Array of strips
int capacity; // Capacity of strip array
int nj // Actual nunber of strips in array
public:
~SkyLine() { delete[] arr; }
int count() {return ny |}
// & function to merge another skyline
7/ to this skyline
SkyLine* Merge(SkyLine *other);
W/ Constructor
SkyLine(int cap)
{
capacity = cap;
arr = new Striplcap];
x
// Function to add a strip ‘st’ to array
void append(Strip *st)
{
11 Check for redundant strip, a strip is
7/ redundant if it has same height or left as previous
Af (n>@ && arr[n-1].ht == st->ht)
return;
if (n>@ 88 arr[n-1].left == st->left)
hitpulnwgookslorgooks ol vide-and-conquer-set-7-he-skyline-prablemy
antswezo1s Divide and Conquer | Set 7 (The Skyline Problem) - GeekstorGoeks
{
arr[n-1].ht = max(arr[n-1].ht, st->ht)5
return;
+
arr[n] = *sts
nes
}
// B utility function to print all strips of
// skyline
void print()
{
for (int i=0; icn; is)
{
cout <<" (" << arr[i].left << ",
<< arr[i].nt <<"), "5
// This function returns skyline for @ given array of buildings
// are{1..h]. This function is similar. to mergesort().
SkyLine *Findskyline(Building arr[], int 1, int h)
if
{
hy
SkyLine tres = new SkyLine(2);
res->append(new Strip(arr[1]-left, arr(1].ht));
res->append(new Strip(arr(1].right, @));
return ress
y
int mid = (1 + n)/25
1/ Recur for left and right halves and merge the two results
Skyline ts] = findSkyline(arr, 1, nid);
Skyline *sr = findskyline(arr, midst, h);
Skyline *res = sl->Merge(sr);
// To avoid memory leak
delete sl;
delete srj
// Return merged skyline
return ress
}
// 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
U skylines
Skyline *res = new SkyLine(this-sn + other-on)5
J/ To store current heights of two skylines
int ht = ®, h2 = @;
// Indexes of strips in two skylines
int i= @ j = @;
while (4 < this->n && j < other->n)
{
// Compare x coordinates of left sides of two
7/ skylines and put the smaller one in result
Af (this-rarr[i].left < other-parr[j].left)
t
int x1 = this-sarr[i).left;
‘1 = this->arr[i].hts
J/ Choose height as max of two heights
int maxh = max(ht, h2);
hitpulnwgookslorgooks ol vide-and-conquer-set-7-he-skyline-prablemy antswezo1s Divide and Conquer | Set 7 (The Skyline Problem) - GeekstorGoeks
append(new Strip(x1, maxh));
>
aise
t
int x2 = other-»arr[j] left;
ha = other-parr{j] hts
int maxh = max(hi, h2)5
append(new Strip(x2, maxh));
>
}
// Tf there are strips left in this skyline or other
7/ skyline
while (i < this->n)
{
res->append(&arr[i});
y
while (5 < other->n)
res->append(&other->arr[j]);
Hs
y
return res;
}
J) drive program
int main()
Building arr{] = {{1, 11, 5), (2, 6, 7}, (3, 13, 9},
{12, 7, 16}, (14,3, 25}, (29, 18, 22},
{23, 13, 29}, (24, 4, 28})5
int n = sizeof(arr)/sizeof(arr[@]);
// Find skyline for given buildings and print the skyline
Skyline *ptr = findSkyline(arr, 8, n-1);
cout << " Skyline for given buildings is \n"3
ptr->print();
return @;
>
Skyline for given buildings is
(2,12), G3, 13), (9, ®), (42, 7), 46, 3), (29, 18),
(22, 3), (23, 13), (29, @),
Time complexity of above recursive implementation is same as Merge Sort.
T(n) = T(nv2) + O(n)
Solution of above recurrence is @{nLogn)
References:
http://facully.kfupm.edu,sa/ies/darwish/stuft/ics353handouts/Ch4Ch5.pdf
‘wwnw.cs.ucf. edu/~sarahb/COP3503/Lectures/DivideAndConquer.ppt
This article is contributed Abhay Rathi. Please write comments if you find anything incorrect, or you want to share
more information about the topic discussed above
ipl geekslorgoeks og vide-and-conquer-set7-he-skyline- problem ont