2532 过桥的时间 Hard

文章介绍了如何利用最小堆优化解决一个关于工人过桥时间的问题。通过维护四个堆来管理不同状态的工人,实现时间复杂度为O(nlogk),空间复杂度为O(k)的解决方案。代码示例使用Python的heapq库实现。
摘要由CSDN通过智能技术生成

Problem: 2532. 过桥的时间

思路

本来一上来就直接暴力做了,结果超时太狠了。之后觉得维护最小堆来获取最小值能够优化时间

解题方法

四个堆:
left_wait1:在当前 cur 时刻,左边已经在桥边等待的工人,以最低效率建堆
left_wait2:在当前 cur 时刻,左边还没有完成放下箱子的工人,以时间建堆
对于right_wait1和right_wait2也是如此。
首先,所有的工人都已在桥边等待,所以入left_wait1队列。对于 n n n个箱子,这里规定只要有工人离开left_wait1队列,就 n − − n-- n
对于桥右边的判断,我们每次要先判断right_wait2中是否有新的工人能够在桥边等待了,如果可以,出堆,之后加入到right_wait1中。而对于right_wait1中的值,直接出堆,之后利用其效率下一次排在桥边的时刻入堆。
对于桥左边的判断,与右边大致相同。
最后,我们要注意,我们这里规定的是左边工人一走,箱子数量就减一,所以并不意味着工人已经从桥的右边回来了。因此,跳出循环后,利用上述逻辑,对right_wait1和right_wait2进行出堆和入堆的判断,直到二者全部为空结束。

复杂度

  • 时间复杂度: O ( n l o g k ) O(nlogk) O(nlogk)

  • 空间复杂度: O ( k ) O(k) O(k)

Code


class Solution:
    def findCrossingTime(self, n: int, k: int, time: List[List[int]]) -> int:
        arr = sorted(time, key=lambda x: x[0] + x[2])
        # left_wait 和 right_wait 分别表示左边和右边工人需要待到什么时刻会有空闲
        left_wait1 = []  # 小于等于当前时间的最小堆
        left_wait2 = []  # 大于当前时间的最小堆
        right_wait1 = [] 
        right_wait2 = []
        cur = 0  # 记录时刻
        for i in range(k):
            heapq.heappush(left_wait1, (-(arr[i][0] + arr[i][2]), -i))
        while n:
            # 查看右边有没有等待的工人
            if n and right_wait2 and cur >= right_wait2[0][0]:
                _, v, i = heapq.heappop(right_wait2)
                heapq.heappush(right_wait1, (v, i))
            elif n and right_wait1:
                v, i = heapq.heappop(right_wait1)
                cur += arr[-i][2]  # 从桥右边往左走
                heapq.heappush(left_wait2, (cur + arr[-i][3], v, i))
            elif n and left_wait2 and cur >= left_wait2[0][0]:
                _, v, i = heapq.heappop(left_wait2)
                heapq.heappush(left_wait1, (v, i))
            elif n and left_wait1:
                n -= 1
                v, i = heapq.heappop(left_wait1)
                cur += arr[-i][0]  # 从桥左边往右走
                heapq.heappush(right_wait2, (cur + arr[-i][1], v, i))
            else:
                cur += 1
        while right_wait1 or right_wait2:
            if right_wait1:
                v, i = heapq.heappop(right_wait1)
                cur += arr[-i][2]
            if right_wait2:
                if cur >= right_wait2[0][0]:
                    _, v, i = heapq.heappop(right_wait2)
                    heapq.heappush(right_wait1, (v, i))
                if len(right_wait1) == 0:
                    cur += 1

        return cur
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值