LeetCode刷题记154
218. 天际线问题
class Solution {
class MyComparator implements Comparator<int[]> {
@Override
public int compare(int[] a, int[] b) {
if (a[0] != b[0]) {
// 无论是建筑的左边还是右边线条,首先按x的位置排序,x小的在前面
return a[0] - b[0];
} else {
// x位置一样的,按照高度排序
// 建筑右边线条矮的在前面,左边线条高的在前面
// 不同建筑的左右线条在同一个位置,则左边那条线在前面
return a[1] - b[1];
}
}
}
public List<List<Integer>> getSkyline(int[][] buildings) {
List<List<Integer>> ans = new ArrayList<>();
PriorityQueue<int[]> lines = new PriorityQueue<int[]>(new MyComparator());
for (int i = 0; i < buildings.length; i ++) {
lines.add(new int[]{buildings[i][0], -buildings[i][2]});
lines.add(new int[]{buildings[i][1], buildings[i][2]});
}
// height存放当前可以涵盖到后面线条的建筑物的左边线条的高度,是大顶堆
PriorityQueue<Integer> height = new PriorityQueue<Integer>((a, b) -> b - a);
height.add(0); // 存放最开始的高度0
int pre_h = 0; // 前一个高度
while (!lines.isEmpty()) {
int[] tmp = lines.poll();
if (tmp[1] < 0) { // 是建筑的左边线条,高度直接入队列
height.add(-tmp[1]);
} else { // 右边线条出现了,那么之前存在的这个高度失效
height.remove(tmp[1]);
}
if (height.peek() != pre_h) { // 当前有效的最高的高度与上一个不一样,说明有转折点
ans.add(Arrays.asList(new Integer[]{tmp[0], height.peek()}));
// ans.add(Arrays.asList(new int[]{tmp[0], height.peek()}));
// 这里有一个神奇的知识点,注释里的写法,obj = Arrays.asList(new int[]{})
// obj是List<int[]>类型的,而不是List<Integer>
pre_h = height.peek();
}
}
return ans;
}
}
这个问题,我感觉好难呀,我没有想明白,所以还是看了题解才做出来的。
关于上面排序的详解: