218.天际线问题

我是研究僧i 提交于 2020-01-29 08:40:25

难度:困难
题目描述:
在这里插入图片描述
在这里插入图片描述
思路总结

  • 方法一:暴力(超时)
  • 方法二:最大堆,具体步骤见注释,trick比较多。
    题解一:(自写,超时)
    思路没啥问题,就是太暴力,没用题目要求用的数据结构,必然会被极端用例逼死。
class Solution:
    def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
        #思路:构造一个数据结构,保存Li小于等于cur和Ri大于等于cur,然后每个点找最大,如果是突变点,分为变大变小两种情况,变大,就取大的;变小,就取小的。
        cur = 0
        pre_val = 0
        if not buildings:return []
        max_val = buildings[-1][1]
        res = []
        all_points_val = []
        for i in range(max_val+1):
            tmp_vals = []
            tmp_max = 0
            for b in buildings:
                if b[0] <= cur and b[1] >= cur:
                    tmp_vals.append(b[2])
            all_points_val.append(tmp_vals)
            cur += 1
        for i in range(len(all_points_val)):
            cur_max, nxt_max = 0, 0
            if all_points_val[i]: cur_max = max(all_points_val[i])
            if i+1 < len(all_points_val) and all_points_val[i+1]: nxt_max = max(all_points_val[i+1])
            if cur_max > pre_val:
                res.append([i, cur_max])
                pre_val = cur_max
            elif nxt_max < pre_val:
                res.append([i, nxt_max])
                pre_val = nxt_max
        return res

题解一结果:
在这里插入图片描述
题解二:(最大堆)
本题trick较多,因此注释比较全面。多多品位。

import heapq
class Solution:
    def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
        #思路:最大堆,每次在判断关键点的时候,移除所有右端点≤当前点的堆顶。
        if not buildings:return []
        points = []
        heap = [[0, float('inf')]]
        res = [[0, 0]]
        #1.将所有端点加入到点集中(每个建筑物的左右端点)
        for l, r, h in buildings:
            points.append((l, -h, r)) #这里负号将最小堆,变成了最大堆
            points.append((r, h, 0)) #r的右端点为0
        #2.将端点从小到大排序
        points.sort() #如果当前点相等,则按照高度升序
        #3.遍历每一个点,分别判断出堆、入堆、添加关键点操作。
        for l, h, r in points:
            while l >= heap[0][1]: #出堆:保证当前堆顶为去除之前建筑物右端点的最大值。
                heapq.heappop(heap)
            if h < 0: #入堆:所有左端点都要入堆
                heapq.heappush(heap, [h, r])
            if res[-1][1] != -heap[0][0]: #关键点:必然是左端点,堆顶,因此需要加负号
                res.append([l, -heap[0][0]])
        return res[1:]    

题解二结果:
在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!