• 边工作边刷题:70天一遍leetcode: day 68-1


    The Skyline Problem

    要点:这题是难题,但是是重点难题,因为google常考,而且很多变形。题本身的pattern就是从左到右更新区间内存在值的最大值(对于这题就是skyline)。最简单的解法就是从左到右根据每个区间的enter/exit point更新存在值的集合。 同时因为区间值集合是不断变化的,需要有个data structure来track当前最大值,priority queue和tree map都可以。
    实现上还有不少细节

    • priority queue中元素类型?一个integer就够了
    • compare function:等于?
      • 注意这个compare function是对时间点sort时候用的,而不是priority queue的,priority queue只根据height来排序
    • 输入输出

    EDIT: 补充更好的方法(更简单,并且beat 98.2% python)

    • 因为building已经按start排好了,不用再排序。heap的最大height就是当前iteration的skyline。当然可能当前的height和当前skyline相同,不更新,这个code的结构就非常简单。
    • 如何定义当前iteration?每个新的start和当前在heap的最大height的end做比较,两个分支:
      • 新的start的存在并且<=heap顶的end,这时候push(push要在loop里把所有start的都push进去,heap顶end也要push)
      • 1的reverse:没新start了,或者新start有空隙。这时候当前iteration就是考虑当前skyline的end(也就会上轮heap的最大值)。pop也是在loop里,把所有已经结束的段pop出来。
      • x: either next start or current end, so it’s in skyline
    • 综上,总循环就是i<n or heap有值
    • 边界条件:
      • 如果start和heap顶end相同,那么push,因为这样height是连续下去的
      • push的时候,多个start相同,要全部push,因为以最大的height为准
      • pop的时候要pop所有dead end:所以第二维也要按最大排序,这样height相同的时候保证end大的作为标准
    • lintcode的输出方式:
      • 不是只需要跳变,而是需要输出非0区间
      • 区间:记录last height,而height变化的时候就输出,只要不是变成0,上一个end和下一个start是同一点,一起更新
      • 非0:如果是0,那么start是不更新的,reset为-1。同理,如果start是-1,下一次跳变更新start
    class Solution(object):
        def getSkyline(self, buildings):
            """
            :type buildings: List[List[int]]
            :rtype: List[List[int]]
            """
            LRH = buildings
            i, n = 0, len(buildings)
            liveHR = []
            skyline = []
            while i<n or liveHR:
                if not liveHR or i<n and LRH[i][0]<=-liveHR[0][1]: # prefer push than pop when ==
                    x = LRH[i][0]
                    while i<n and x==LRH[i][0]:
                        heapq.heappush(liveHR, (-LRH[i][2], -LRH[i][1]))
                        i+=1
                else: # time to pop as next start is greater or no next
                    x = -liveHR[0][1]
                    while liveHR and -liveHR[0][1]<=x: # error: not ==x, <=x, other dead ones are not popped
                        heapq.heappop(liveHR)
                height = len(liveHR) and -liveHR[0][0] # error: not or, and
                if not skyline or skyline[-1][1]!=height:
                    skyline.append((x, height)) # x is always valid, either next start or current end
            return skyline
    
    
  • 相关阅读:
    20172319 实验五 《网络编程与安全》实验报告
    20172319 《程序设计与数据结构》第11周学习总结
    20172319 实验四 《Android程序设计》实验报告
    20172312 2018-2019-1 《程序设计与数据结构》第八周学习总结
    20172312 2018-2019-1 《程序设计与数据结构》第七周学习总结
    20172312 2018-2019-1 《程序设计与数据结构》第六周学习总结
    20172312 2018-2019-1 《程序设计与数据结构》第五学习总结
    20172312 2018-2019-1 《程序设计与数据结构》第四周学习总结
    20172312 2018-2019-1 《程序设计与数据结构》实验一报告
    20172312 2018-2019-1 《程序设计与数据结构》第3周学习总结
  • 原文地址:https://www.cnblogs.com/absolute/p/5690354.html
Copyright © 2020-2023  润新知