[LeetCode-JAVA] The Skyline Problem
題目:題目太長了,見鏈接-- >?The Skyline Problem?
Notes:
- The number of buildings in any input list is guaranteed to be in the range?[0, 10000].
- The input list is already sorted in ascending order by the left x position?Li.
- The output list must be sorted by the x position.
- There must be no consecutive horizontal lines of equal height in the output skyline. For instance,?[...[2 3], [4 5], [7 5], [11 5], [12 7]...]?is not acceptable; the three lines of height 5 should be merged into one in the final output as such:?[...[2 3], [4 5], [12 7], ...]
題意:記錄每一次建筑的拐點,連續的相同高度,只記錄最前面的。
思路:將每一個豎線按順序存入,對于每一個矩形,都有高度相同的兩條豎線,為了在一次掃描的時候,能將所有的豎線都加入,利用一個小技巧,將右邊界的高度存為負值,恰好可以對其標記。將存入的list排序,需要自定義一個比較器比較a[],b[],如果a[0] == b[0] 說明豎線重合,這個時候應該是高的在前面,如果a[0] != b[0] 只需按照a[0]b[0]從小到大即可。
最后在遍歷list的時候,為了滿足note4,即連續相同的高度只記錄最前即可,因此需要用到pre和cur分別記錄當前的最高和上一次的最高。在判斷的時候,需要維護每次當前的最大值,可以用PriorityQueue權重隊列,其構造原理是大頂堆,即根節點為最小(或最大)的二叉樹,默認跟為最小值,根據題意,本題需要自己定義一個比較器,根保存當前最大值(可以注意我下面說的堆個隊里,是同一個概念,為了方便理解,不同的時候用了不同的說法)。
最核心的思想:掃描到左邊界的時候,將高度加入到大頂堆,cur的值去peek即為當前的最大值,當cur和pre不同的時候,將坐標加入結果隊列即可,當為右邊界時(高度為負值),證明該矩形已經到頭,在堆中去掉其高度值,如果此時隊列為空,則證明此處非連續,即此時應加入的高度為0,如果不為空,則更新相應當前最高即可。
代碼:
public class Solution {//大頂推比較器public class MaxCom implements Comparator<Integer> {public int compare(Integer a, Integer b){return b - a ; // 大的在堆的頂端 }} //數組比較器public class ArrayCom implements Comparator<int[]> {public int compare(int[] a, int[] b) {if(a[0] != b[0]) return a[0] - b[0]; //先按左邊界進行排序return b[1] - a[1]; // 相等 則高的在前面 }}public List<int[]> getSkyline(int[][] buildings) { List<int[]> res = new ArrayList<int[]>(); PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new MaxCom());List<int[]> ver = new ArrayList<int[]>(); // 記錄每一個豎線for(int i = 0 ; i < buildings.length ; i++){int[] temp = buildings[i]; ver.add(new int[]{temp[0], temp[2]}); // 左邊界豎線ver.add(new int[]{temp[1], -temp[2]}); // 右邊界豎線 為了區分 存入負值 }Collections.sort(ver, new ArrayCom());int cur = 0, pre = 0;for(int i = 0 ; i < ver.size() ; i++){int[] temp = ver.get(i);if(temp[1] > 0) { // 左邊界maxHeap.offer(temp[1]); //高度入隊cur = maxHeap.peek(); // 當前最高的}else { // 右邊界maxHeap.remove(-temp[1]); // 將對應的高度從堆中刪除 這里就是右邊存負值的方便之處cur = (maxHeap.peek() == null ? 0 : maxHeap.peek()); // 如果右邊界是最后一個則高度為0,否則更新當前最高 }if(cur != pre) { // 與上一個最高的不相等res.add(new int[]{temp[0], cur});pre = cur; // 保存當前高度為下一次的前面高度 }}return res; } }?參考鏈接:http://blog.csdn.net/xudli/article/details/46349383
轉載于:https://www.cnblogs.com/TinyBobo/p/4592061.html
總結
以上是生活随笔為你收集整理的[LeetCode-JAVA] The Skyline Problem的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 页面向上滚动
- 下一篇: DSP与STM32区别