class Edge {
int x;
int height;
boolean isStart;
public Edge(int x, int height, boolean isStart) {
this.x = x;
this.height = height;
this.isStart = isStart;
}
}
public List<int[]> getSkyline(int[][] buildings) {
List<int[]> result = new ArrayList<int[]>();
if (buildings == null || buildings.length == 0
|| buildings[0].length == 0) {
return result;
}
List<Edge> edges = new ArrayList<Edge>();
// add all left/right edges
for (int[] building : buildings) {
Edge startEdge = new Edge(building[0], building[2], true);
edges.add(startEdge);
Edge endEdge = new Edge(building[1], building[2], false);
edges.add(endEdge);
}
// sort edges
Collections.sort(edges, new Comparator<Edge>() {
public int compare(Edge a, Edge b) {
if (a.x != b.x)
return Integer.compare(a.x, b.x);
if (a.isStart && b.isStart) {
return Integer.compare(b.height, a.height);
}
if (!a.isStart && !b.isStart) {
return Integer.compare(a.height, b.height);
}
return a.isStart ? -1 : 1;
}
});
// process edges
PriorityQueue<Integer> heightHeap = new PriorityQueue<Integer>(10, Collections.reverseOrder());
for (Edge edge : edges) {
if (edge.isStart) {
if (heightHeap.isEmpty() || edge.height > heightHeap.peek()) {
result.add(new int[] { edge.x, edge.height });
}
heightHeap.add(edge.height);
} else {
heightHeap.remove(edge.height);
if(heightHeap.isEmpty()){
result.add(new int[] {edge.x, 0});
}else if(edge.height > heightHeap.peek()){
result.add(new int[]{edge.x, heightHeap.peek()});
}
}
}
return result;
}