LeetCode218 The SkyLine problem

this problem is a kind of problem that is easy to understand, but have not much of experience in solving such problems.
what is there not to understand? well, there are few questions:

  1. how do we output the skyline? answer: A key point is the left endpoint of a horizontal line segment. and an example of the output is: [ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ], which each point is the corrdinate of that horizonital line segment
  2. how do we find all those critical points? let’s imgine a sweep line from left to right, and each time if we meet a line that suddenly changing in its height.

well, it easier to say than done.
and the solution provided by leetcode is Divide and conquer??? I lost my words…in one thousand universe, none of myself will think of Divide and conquer!

However, let’s not think of this question in a hard way. we noticed that the left point of each segment is the key point of the sky line, maybe if we sort them in order and to see if the segment are overlapped or not. this remains me of that arrange meeting room problems. but in meeting room problem, we donot need to worry about them in two-dimension. but this skyline problem does. not only do we need to consider the overlap between starting point and end point, we also need to consider the height overlap between all those line segment.

refer:

//reference: youtube happyfgirlzt, not fully understand though
class Solution {
    public List<List<Integer>> getSkyline(int[][] buildings) {
        TreeMap<Integer, List<int[]>> map = new TreeMap<>();
        for (int[] b: buildings) {
            map.putIfAbsent(b[0], new ArrayList<>()); //use starting and end point as the key, and use this line segment as the value
            map.putIfAbsent(b[1], new ArrayList<>());
            map.get(b[0]).add(b); //starting point - every interval with the same starting point
            map.get(b[1]).add(b); //end point- every interval with the same ending point
        }
        
        PriorityQueue<int[]> maxHeap = new PriorityQueue<>((a, b)->(b[2] - a[2])); //sort by height
        
        List<List<Integer>> res = new ArrayList<>();
        
        for (int a: map.keySet()) { //for every key in treemap
            List<int[]> bs = map.get(a);
            for (int[] b: bs) { //
                if (b[0] == a) { //if this current key a is a starting key
                    maxHeap.offer(b);  //we offer that line segment to maxHeap
                } else { //if this current key a is a ending key
                    maxHeap.remove(b); //then we remove this segment
                } //in short, maxHeap will only contains all the
            }
            if (maxHeap.size() == 0) { //if maxHeap left nothing
                List<Integer> tmp = new ArrayList<>();
                tmp.add(a);
                tmp.add(0);
                res.add(tmp); //then we have a interval point
            } else { //if not
                int maxHeight = maxHeap.peek()[2]; //we peek the heightest
                if (res.size() == 0 || res.get(res.size() - 1).get(1) != maxHeight) {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(a);
                    tmp.add(maxHeight);
                    res.add(tmp);
                }
            }
            
        }
        return res;
    }

}

and the leetcode solution provide a devide and conquer way, which is hard to understand…

Nevertheless, I can’t see if there is any connection between this problem and Segment Tree…

posted @ 2020-12-12 00:56  EvanMeetTheWorld  阅读(19)  评论(0)    收藏  举报