Skip to content

Instantly share code, notes, and snippets.

@shailrshah
Created November 12, 2017 03:59
Show Gist options
  • Save shailrshah/1cc0eeb18666a13f84710ae5bd2a3f20 to your computer and use it in GitHub Desktop.
Save shailrshah/1cc0eeb18666a13f84710ae5bd2a3f20 to your computer and use it in GitHub Desktop.
import java.util.SortedMap;
class CriticalPoint implements Comparable<CriticalPoint>{
int x;
int y;
int isRightEnd;
CriticalPoint(int x, int y, int isRightEnd) {
this.x = x;
this.y = y;
this.isRightEnd = isRightEnd;
}
int getX() {
return this.x;
}
int getY() {
return this.y;
}
int getIsRightEnd() {
return this.isRightEnd;
}
@Override
public int compareTo(CriticalPoint other) {
if(this.getX() != other.getX())
return this.getX() - other.getX();
else {
if(this.getIsRightEnd() != other.getIsRightEnd())
return this.getIsRightEnd() - other.getIsRightEnd();
else {
if(this.getIsRightEnd() == 1)
return this.getY() - other.getY();
else return other.getY() - this.getY();
}
}
}
}
public class Solution {
/* First, sort the critical points.
Then scan across the critical points from left to right.
When we encounter the left edge of a rectangle, we add that rectangle to the heap with its height as the key.
When we encounter the right edge of a rectangle, we remove that rectangle from the heap.
(This requires keeping external pointers into the heap.)
Finally, any time we encounter a critical point,
after updating the heap we set the height of that critical point to the value peeked from the top of the heap. */
public List<int[]> getSkyline(int[][] buildings) {
List<CriticalPoint>criticalPoints = new ArrayList<>();
for(int[] building : buildings) {
int left = building[0], right = building[1], height = building[2];
criticalPoints.add(new CriticalPoint(left, height, 0));
criticalPoints.add(new CriticalPoint(right, height, 1));
}
Collections.sort(criticalPoints);
SortedMap<Integer, Integer> map = new TreeMap<>();
List<int[]> collect = new ArrayList<>();
for(int i = 0; i < criticalPoints.size(); i++) {
CriticalPoint c = criticalPoints.get(i);
int x = c.getX(), y = c.getY();
if(c.getIsRightEnd() == 0) {
map.put(y, map.getOrDefault(y, 0) + 1);
if(y == map.lastKey() && map.get(y) == 1)
collect.add(new int[] {x, y});
}
else {
map.put(y, map.get(y) - 1);
if(map.get(y) == 0)
map.remove(y);
if(map.isEmpty())
collect.add(new int[]{x, 0});
else {
int top = map.lastKey();
if(y > top)
collect.add(new int[]{x, top});
}
}
}
return collect;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment