1. 程式人生 > >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; } }