题目:https://leetcode-cn.com/problems/the-skyline-problem/
题目要我们求轮廓,其实就是高的盖住矮的,然后记录那些转折点。
对于每一个建筑物,我们要记录其开始点,结束点,以便知道它什么时候没了。
我们的思路就是:记录当前的最高点,如果它还在(结束点还没到),它就可以继续遮住那些矮(不需要统计),直到结束点到了,我们就把它删掉。 对于这一步骤我们可以用优先队列实现。
而当我们记录点时,我们可以将起点赋值为 负数,终点赋为正数。
class Solution {
public List<List<Integer>> getSkyline(int[][] buildings) {
List<List<Integer>> ans=new LinkedList();
List<int[]> builds=new LinkedList();
for(int[] x:buildings){
builds.add(new int[]{x[0],-x[2]}); //起点
builds.add(new int[]{x[1],x[2]}); //终点
}
Collections.sort(builds,new Comparator<int[]>(){
public int compare(int[] a,int[] b){
if(a[0]!=b[0]) return a[0]-b[0];
//当起点相同时,因为高度为负数,所以高度大的还是排在前面
return a[1]-b[1];
}
});
Queue<Integer> maxq=new PriorityQueue((n1,n2)->(int)n2-(int)n1);
maxq.add(0); //添加最后结束的点(最后结束的点为地面)
int cur=0,pre=0;
for(int[] x:builds){
//为负数,还没遇到过,添加
if(x[1]<0)
maxq.add(-x[1]);
//之前出现过,删除
else
maxq.remove(x[1]);
cur=maxq.peek();
//如果最大被删除,第二小的就添加进来
if(cur!=pre){
ans.add(Arrays.asList(x[0],cur));
pre=cur;
}
}
return ans;
}
}