[leetcode] The Skyline Problem
O(n^2) solution: Sweep
public List<List<Integer>> getSkyline(int[][] buildings) {
TreeSet<Integer> edgeSet = new TreeSet<>();
for(int[] building : buildings){
edgeSet.add(building[0]);
edgeSet.add(building[1]);
}
List<Integer> positions = new ArrayList<>(edgeSet);
Collections.sort(positions);
List<List<Integer>> res = new ArrayList<>();
int maxHeight, left, right, height;
for(int position : positions){
maxHeight = 0;
for(int[] building: buildings){
left = building[0];
right = building[1];
height = building[2];
if(left<=position && position < right){
maxHeight = Math.max(maxHeight, height);
}
}
if(res.isEmpty() || res.get(res.size()-1).get(1) != maxHeight){
res.add(Arrays.asList(position, maxHeight));
}
}
return res;
}
O(nlogn) solution: sweep + PQ/BST
class Solution {
public List<int[]> getSkyline(int[][] buildings) {
List<int[]> res = new ArrayList<>();
List<int[]> height = new ArrayList<>();
for (int[] building : buildings) {
// start point has negative height value
height.add(new int[]{building[0], -building[2]});
// end point has normal height value
height.add(new int[]{building[1], building[2]});
}
Collections.sort(height, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
if (a[0] == b[0]) {
return a[1] - b[1];
} else {
return a[0] - b[0];
}
}
});
// Use a maxHeap to store possible heights
// But priority queue does not support remove in lgn time
// treemap support add, remove, get max in lgn time, so use treemap here
// key: height, value: number of this height
TreeMap<Integer, Integer> pq = new TreeMap<>();
pq.put(0, 1);
// Before starting, the previous max height is 0;
int prev = 0;
// visit all points in order
for (int[] h : height) {
// a start point, add height
if (h[1] < 0) {
pq.put(-h[1], pq.getOrDefault(-h[1], 0) + 1);
} else { // a end point, remove height
if (pq.get(h[1]) > 1) {
pq.put(h[1], pq.get(h[1]) - 1);
} else {
pq.remove(h[1]);
}
}
int cur = pq.lastKey();
// compare current max height with previous max height, update result and
// previous max height if necessary
if (cur != prev) {
res.add(new int[]{h[0], cur});
prev = cur;
}
}
return res;
}
}
https://www.youtube.com/watch?v=GSBLe8cKu0s
https://leetcode.com/problems/the-skyline-problem/discuss/61193/Short-Java-solution

浙公网安备 33010602011771号