LeetCode218. 天际线问题

题目链接:LeetCode218

题解

如果按照一个矩形一个矩形处理会非常麻烦,我们把这些矩形拆成两个点,一个左上角顶点,一个右上角顶点。将所有顶点按照横坐标进行排序然后开始遍历,遍历时通过一个堆来得知当前图形的最高位置,堆顶是所有顶点中最高的点,只要这个点没被移出堆,就说明这个最高的矩形还没结束。对于左顶点,我们将其加入堆中,对于右顶点,我们找出堆中相应的最顶点,然后移出左顶点,同时也意味着这个矩形的结束,为了区分左右顶点,我们以负数作为左顶点,正数作为右顶点

代码
public class Solution {
    	public static List<int[]> getSkyline(int[][] buildings) {
		List<int[]> res = new ArrayList<>();
		List<int[]> height = new ArrayList<>();
		// 拆解矩形的左右顶点
		for (int[] b : buildings) {
			height.add(new int[] { b[0], -b[2] });// 左顶点存负数
			height.add(new int[] { b[1], b[2] });// 右顶点存正数
		}
		// 根据横坐标对列表排序,相同横坐标的点纵坐标小的排在前面
		Collections.sort(height, 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> pq = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
			public int compare(Integer i1, Integer i2) {
				return i2 - i1;
			}
		});
		pq.add(0);// 首先加入地平线起始点0
		int prev = 0;// prev用于记录上次keyPoint的高度
		for (int[] h : height) {
			if (h[1] < 0)// 左顶点加入堆
				pq.add(-h[1]);
			else
				pq.remove(h[1]);// 将右顶点对应的左顶点移出
			int cur = pq.peek();
			if (prev != cur) {// 如果堆的新顶部和上个keypoint高度不一样,则加入一个新的keypoint
				res.add(new int[] { h[0], cur });
				prev = cur;
			}
		}
		return res;
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数学家是我理想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值