[leetcode] The Skyline Problem

 O(n^2) solution: Sweep

    public List<List<Integer>> getSkyline(int[][] buildings) {
        TreeSet<Integer> edgeSet = new TreeSet<>();
        for(int[] building : buildings){
            edgeSet.add(building[0]);
            edgeSet.add(building[1]);
        }
        List<Integer> positions = new ArrayList<>(edgeSet);
        Collections.sort(positions);
        
        List<List<Integer>> res = new ArrayList<>();
        int maxHeight, left, right, height;
        
        for(int position : positions){
            maxHeight = 0;
            
            for(int[] building: buildings){
                left = building[0];
                right = building[1];
                height = building[2];
                
                if(left<=position && position < right){
                    maxHeight = Math.max(maxHeight, height);
                }
            }
            
            if(res.isEmpty() || res.get(res.size()-1).get(1) != maxHeight){
                res.add(Arrays.asList(position, maxHeight));
            }
            
        }
        
        return res;
    }

  

 

 O(nlogn) solution: sweep + PQ/BST

class Solution {
    public List<int[]> getSkyline(int[][] buildings) {
        List<int[]> res = new ArrayList<>();
        List<int[]> height = new ArrayList<>();
        for (int[] building : buildings) {
            // start point has negative height value
            height.add(new int[]{building[0], -building[2]});
            // end point has normal height value
            height.add(new int[]{building[1], building[2]});
        }
        Collections.sort(height, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                if (a[0] == b[0]) {
                    return a[1] - b[1];
                } else {
                    return a[0] - b[0];
                }
            }
        });
        // Use a maxHeap to store possible heights
        // But priority queue does not support remove in lgn time
        // treemap support add, remove, get max in lgn time, so use treemap here
        // key: height, value: number of this height
        TreeMap<Integer, Integer> pq = new TreeMap<>();
        pq.put(0, 1);
        // Before starting, the previous max height is 0;
        int prev = 0;
        // visit all points in order
        for (int[] h : height) {
            // a start point, add height
            if (h[1] < 0) {
                pq.put(-h[1], pq.getOrDefault(-h[1], 0) + 1);
            } else {  // a end point, remove height
                if (pq.get(h[1]) > 1) {
                    pq.put(h[1], pq.get(h[1]) - 1);
                } else {
                    pq.remove(h[1]);
                }
            }
            int cur = pq.lastKey();
            // compare current max height with previous max height, update result and 
            // previous max height if necessary
            if (cur != prev) {
                res.add(new int[]{h[0], cur});
                prev = cur;
            }
        }
        return res;
    }
}

 

https://www.youtube.com/watch?v=GSBLe8cKu0s 

https://leetcode.com/problems/the-skyline-problem/discuss/61193/Short-Java-solution

 

posted @ 2022-11-02 01:55  jdflyfly  阅读(15)  评论(0编辑  收藏  举报