Leetcode 218. The Skyline Problem

Leetcode 218. The Skyline Problem_第1张图片
方法1: 这道题目目前是超过了我的能力范围的,不论是在数据结构的使用还是逻辑的理解上来说都是比较难的。这边我建议复盘的时候看这个视频,讲得很清楚,然后看完了,自己写一遍,现在我自己是没去实现的,因为感觉太难了,做了意义不大。然后记得还要去分析复杂度。

class Solution {
    private class Point implements Comparable<Point>{
        private int x;
        private int height;
        private boolean isStart;
        
        public Point(int x, int height, boolean isStart) {
            this.x = x;
            this.height = height;
            this.isStart = isStart;
        }
        
        // 比较规则复杂,主要是考虑到了三种边界情况
        public int compareTo(Point p) {
            if (this.x != p.x) {
                return this.x - p.x;
            } else {
                if (this.isStart && p.isStart) {
                    return p.height - this.height;
                } 
                if (!this.isStart && !p.isStart) {
                    return this.height - p.height;
                }
                return this.isStart?-1:1;
            }
        }
        
    }
    
    public List<List<Integer>> getSkyline(int[][] buildings) {
        int len = buildings.length;
        if (len == 0 || buildings[0].length == 0) {
            return new ArrayList<List<Integer>>();
        }
        // 每栋建筑有两个关键点
        Point[] points = new Point[len * 2];
        int index = 0;
        
        // 初始化所有关键点的数组
        for (int[] building : buildings) {
            int start = building[0];
            int end = building[1];
            int h = building[2];
            points[index++] = new Point(start,h,true);
            points[index++] = new Point(end,h,false);
            
        }
        // 将这些点按照我们希望的顺序排序
        Arrays.sort(points);
        // 用Collections.reverseOrder()来建立大根堆,这样就可以找到当前最高的高度
        PriorityQueue<Integer> queue = new PriorityQueue<>(Collections.reverseOrder());
        queue.offer(0);
        List<List<Integer>> res = new ArrayList<>();
        
        int prevMaxVal = 0;
        for (Point point : points) {
            if (point.isStart) {
                queue.offer(point.height);
                int curMaxVal = queue.peek();
                // 如果最大值变化了(只能变大),就说明这个点应该被记录
                if (curMaxVal > prevMaxVal) {
                    List<Integer> l = new ArrayList<>();
                    l.add(point.x);
                    l.add(point.height);
                    res.add(l);
                    prevMaxVal = curMaxVal;
                }
                
            } else {
                queue.remove(point.height);
                int curMaxVal = queue.peek();
                // 最大值变化了(只能变小),记录当前点
                if (curMaxVal < prevMaxVal) {
                    List<Integer> l = new ArrayList<>();
                    l.add(point.x);
                    l.add(curMaxVal);
                    res.add(l);
                    prevMaxVal = curMaxVal;
                }
                
            }
        }
        
        return res;
    }

}

总结:

你可能感兴趣的:(Leetcode,heap,array)