题目链接:https://leetcode.com/problems/the-skyline-problem/
示例代码:
public class Solution {
public List<int[]> getSkyline(int[][] buildings) {
List<int[]> res = new ArrayList<int[]>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>(){
@Override
public int compare(Integer a, Integer b) {
return b - a;
}
});
List<int[]> bl = new ArrayList<int[]>();
for(int i=0; i<buildings.length; i++) {
int[] b = buildings[i];
bl.add(new int[]{b[0], b[2]});
bl.add(new int[]{b[1], -b[2]});
}
Collections.sort(bl, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
if(a[0]!=b[0]) return a[0] - b[0];
else return b[1] - a[1];
}
});
int pre = 0, cur = 0;
for(int i=0; i<bl.size(); i++) {
int[] b = bl.get(i);
if(b[1]>0) {
maxHeap.add(b[1]);
cur = maxHeap.peek();
} else {
maxHeap.remove(-b[1]);
cur = (maxHeap.peek()==null) ? 0 : maxHeap.peek();
}
if(cur!=pre) {
res.add(new int[]{b[0], cur});
pre = cur;
}
}
return res;
}
}
总结:
重点在于数据结构的应用,个人对点排序有点疑惑,做个总结记录。
从图中4个点的顺序总结规律如下:
sort(height.begin(), height.end(), [](const node &a, const node &b) {
if (a.x != b.x) return a.x < b.x;
else if (a.type == LEFT && b.type == LEFT) return a.y > b.y;
else if (a.type == RIGHT && b.type == RIGHT) return a.y < b.y;
else return a.type == LEFT;// x 相同,左点优先
});
应用一些小技巧,可以简化判断:
比如如果将右点的高度设为负数,当两点X相同时,就可按照高度从大到小排列:
for(int i=0; i<buildings.length; i++) {
int[] b = buildings[i];
bl.add(new int[]{b[0], b[2]});
bl.add(new int[]{b[1], -b[2]});
}
Collections.sort(bl, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
if(a[0]!=b[0]) return a[0] - b[0];//x 从小到大
else return b[1] - a[1];// y从大到小
}
});
同理可将左点的高度设为负数。