0% found this document useful (0 votes)
84 views

Skyline Problem

The document describes an algorithm to draw the skyline formed by a list of overlapping buildings, where each building is defined by its height, start point, and end point. It first sorts the building start and end points, then uses a sweep line algorithm with a max-height data structure to maintain the visible skyline at each point, drawing horizontal and vertical lines as the max height changes. It discusses using a hash map or binary min-heap for the max-height structure to improve the time complexity to O(N log N).

Uploaded by

abhi74
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

Skyline Problem

The document describes an algorithm to draw the skyline formed by a list of overlapping buildings, where each building is defined by its height, start point, and end point. It first sorts the building start and end points, then uses a sweep line algorithm with a max-height data structure to maintain the visible skyline at each point, drawing horizontal and vertical lines as the max height changes. It discusses using a hash map or binary min-heap for the max-height structure to improve the time complexity to O(N log N).

Uploaded by

abhi74
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

 

Interview Camp 

 
Technique: Line Sweep 

Level: Hard 

You are given a list of buildings that are part of a skyline. For each building, you 
are given the height, start and end points.  
 
For example, if a building has ​[height=5, start=1, end=4]​, 
it represents a building of height 5 from point 1 on a number line to point 4. 
 

 
 
Given a list of such buildings that may overlap, you want to draw the skyline. 
 
Questions to Clarify: 
Q. Can we assume that we have a draw function that takes care of drawing? 
A. Yes 

Solution: 
We use line sweep to loop through the buildings. We sort the start and end points, and loop
through them. When we loop, we keep a data structure (let’s say a map) that tells us the highest
building among the current overlapping buildings. The highest height is the one we draw.

BuildingMap = empty // hash map of current overlapping buildings


currentMax = 0 // max height currently
for i -> 0 to points.length - 1:
if points[i].isStart == True
add points[i] to BuildingMap
if points[i] is > currentMax
draw height currentMax until this point
currentMax = points[i].height
else: // end of a building
remove points[i] from BuildingMap
if currentMax = points[i].height // this was tallest
building

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

draw currentMax till this point


currentMax = find max height in BuildingMap

The above pseudocode will draw the top of the skyline, but won't draw the vertical lines.
You can modify it to draw vertical lines pretty easily (full pseudocode below).

In the above algorithm, we use a hash table to keep track of overlapping buildings. This makes
it quick to add and remove buildings. But, it is slow to find the max height. It takes O(n) to
find the max height, and the time complexity of this algorithm becomes O(n^2).

Can we improve the time to find the max height? Yes we can, using a heap. With a heap, we
can insert and delete nodes in​ log(N)​ time, and find the max in ​O(1) ​time. This reduces the
overall complexity to ​O(Nlog(N))​.
There is one caveat though - to delete a node from the heap, we need a pointer to the node.
So, we keep a hash map with pointers to the heap nodes. This data structure ends up similar
to a linked hash map, except with a heap instead of a linked list.
More details about heaps are in the Heap section.

Alternatively, you can also use a Binary Search Tree instead of a Heap if you like.

In the interview, we will call the data structure BuildingMap and implement it as a Hashed Heap
only if the interviewer asks us to. In most cases, the interviewer will not ask you to implement it.

Pseudocode: 
Turn Buildings into Points
Sort Points by location

BuildingMap = empty // hash map of current overlapping buildings


currentMax = 0 // max height currently
for i -> 0 to points.length - 1:
if points[i].isStart == True
add points[i] to BuildingMap
if points[i] is > currentMax
draw horizontal line of height currentMax until this point
draw vertical line from currentMax's start to points[i].height
currentMax = points[i].height
else: // end of a building
remove points[i] from BuildingMap
if currentMax = points[i].height // this was tallest building
draw horizontal line of height currentMax till this point
oldMax = currentMax
currentMax = find max height in BuildingMap
draw vertical line from currentMax to oldMax

Test Cases: 

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

Edge Cases: No building, building height 0 


Base Cases: Single building, 2 buildings (overlap, no overlap) 
Regular Cases: Many buildings (overlap/no overlap) 

Time Complexity:​ O(Nlog(N)) 

Space Complexity:​ O(N) 


 
public static void drawSkyline(Building[] buildings) {
List<Point> points = new ArrayList<>();
for (Building building : buildings) {
points.add(new Point(building.getHeight(), building.getStart(), true));
points.add(new Point(building.getHeight(), building.getEnd(), false));
}

Collections.sort(points);

BuildingMap map = new BuildingMap();


int currentMax = 0;
int currentMaxStartX = 0;
for (int i = 0; i < points.size(); i++) {
Point point = points.get(i);
if (point.isStart()) {
map.put(point.getHeight());
if (point.getHeight() > currentMax) {
drawHorizontal(currentMax, currentMaxStartX, point.getLocation());
drawVertical(point.getLocation(), currentMax, point.getHeight());
currentMax = point.getHeight();
currentMaxStartX = point.getLocation();
}
} else {
map.remove(point.getHeight());
if (currentMax == point.getHeight()) {
drawHorizontal(currentMax, currentMaxStartX, point.getLocation());
int oldMax = currentMax;
currentMax = map.getMax();
currentMaxStartX = point.getLocation();
drawVertical(point.getLocation(), currentMax, oldMax);
}
}
}
}

/*
* Helper Code. Ask the interviewer if they want you to implement.
*/
public static class Building {
int height;

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

int start;
int end;

public Building(int height, int start, int end) {


super();
this.height = height;
this.start = start;
this.end = end;
}

public int getHeight() {


return height;
}

public int getStart() {


return start;
}

public int getEnd() {


return end;
}
}

public static class Point implements Comparable<Point> {


int height;
int location;
boolean isStart;

public Point(int height, int location, boolean isStart) {


super();
this.height = height;
this.location = location;
this.isStart = isStart;
}

public int getHeight() {


return height;
}

public int getLocation() {


return location;
}

public boolean isStart() {


return isStart;
}

@Override
public int compareTo(Point other) {
if (location == other.getLocation())

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

return isStart ? -1 : 1;
return location > other.getLocation() ? 1 : -1;
}
}

/*
* This is the Hash Table implementation of BuildingMap.
*
* Time Complexity: O(1) for insertion, O(N) for max lookup.
*/
public static class BuildingMap {
HashMap<Integer, Integer> map;

public BuildingMap() {
map = new HashMap<>();
}

public void put(int height) {


if (map.containsKey(height)) {
map.put(height, map.get(height)+1);
} else {
map.put(height, 1);
}
}

public void remove(int height) {


if (!map.containsKey(height))
return;
map.put(height, map.get(height)-1);
if (map.get(height) <= 0)
map.remove(height);
}

public int getMax() {


int max = 0;
for (Integer key : map.keySet()) {
if (key > max)
max = key;
}
return max;
}
}

/*
* This is the Hashed Heap implementation of BuildingMap.
* The interviewer won't ask you to implement the actual Heap in addition to
* this question, because that would be too much work. You can assume that
* a Heap class is provided to you.
*

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

* Note for Java Users: Java has a PriorityQueue class that is a heap, but
* we cannot use it in this problem. In PriorityQueue, you cannot give a
* node to delete in O(logN) time. It’s delete() function takes O(N) time
* because it searches for the node before deleting it.
*
* Time Complexity: O(log(N)) for insertion, O(1) for max lookup
*/
public static class BuildingMapWithHeap {
// The map stores a list of nodes because there can be multiple
// buildings with the same height.
HashMap<Integer, List<Node>> map;
Heap<Integer> heap;

public BuildingMap() {
map = new HashMap<>();
heap = new Heap<>();
}

public void put(int height) {


Node heapNode = heap.insert(height);
if (map.containsKey(height)) {
((List<Node>) map.get(height)).add(heapNode);
} else {
List<Node> list = new ArrayList<>();
list.add(heapNode);
map.put(height, list);
}
}

public void remove(int height) {


if (!map.containsKey(height))
return;
Node toRemove = map.get(height).remove(0);
heap.remove(toRemove);
if (map.get(height).isEmpty())
map.remove(height);
}

public int getMax() {


if (heap.isEmpty())
return 0;
return heap.getMax();
}
}

public static class Heap {


// no need to implement

 
 
© ​2017 Interview Camp (interviewcamp.io) 
 
Interview Camp 

public static void drawHorizontal(int y, int x1, int x2) {


// no need to implement
}

public static void drawVertical(int x, int y1, int y2) {


// no need to implement
}
 

 
 
© ​2017 Interview Camp (interviewcamp.io) 

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy