Given n buildings, each building is an rectangle located on x-axis, and indicated by (x1, x2, height). Calculate the outline of all buildings. Output them in order.
Solution
Sweeping Line Algorithm.
Sweep from left to right, always try to find the largest height of the rectangle.
First make sure the rectangles are sorted. While sweeping, if sees an building-start, insert the height to the heap. If a building-end, remove from the heap. Then the current maximum height is the max point in the heap.
public int[] skyline(List<Building> bds, int min, int max) { int[] output = new int[max - min];
List<Edge>[] edges = new List[max - min]; for (int i = 0; i < edges.length; i++) { edges[i] = new ArrayList<Edge>(); } for (Building b : bds) { // put all edges into an array of edges edges[b.from].add(new Edge(b, true)); edges[b.to].add(new Edge(b, false)); }
Queue<Building> heap = new PriorityQueue<Building>(100, new Comparator<Building>() { public int compare(Building b1, Building b2) { return b2.height - b1.height; } }); for (int i = 0; i < edges.length; i++) { // insert or remove each building at position i into max heap for (Edge e : edges[i]) { if (e.isEnter) { heap.add(e.building); } else { heap.remove(e.building); } } // then culculate the current hight, which is top of the heap if (!heap.isEmpty()) { output[i] = heap.peek().height; } }
return output; }
static class Edge { Building building; boolean isEnter;
public Edge(Building bld, boolean enter) { building = bld; isEnter = enter; } }
static class Building { int from; int to; int height;
public Building(int a, int b, int c) { from = a; to = b; height = c; } }