Leetcode 1094:拼车(超详细的解法!!!)

博客围绕顺风车行程接送任务展开,根据行程计划表和车子座位数判断能否完成接送。先尝试区间合并解法但遇问题,后采用建立数组累加区间数的方法,还可对区间端点标记优化。若区间范围大,可借鉴Leetcode 253解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设你是一位顺风车司机,车上最初有 capacity 个空座位可以用来载客。由于道路的限制,车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向,你可以将其想象为一个向量)。

这儿有一份行程计划表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了你的第 i 次行程信息:

  • 必须接送的乘客数量;
  • 乘客的上车地点;
  • 以及乘客的下车地点。

这些给出的地点位置是从你的 初始 出发位置向前行驶到这些地点所需的距离(它们一定在你的行驶方向上)。

请你根据给出的行程计划表和车子的座位数,来判断你的车是否可以顺利完成接送所用乘客的任务(当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false)。

示例 1:

输入:trips = [[2,1,5],[3,3,7]], capacity = 4
输出:false

示例 2:

输入:trips = [[2,1,5],[3,3,7]], capacity = 5
输出:true

示例 3:

输入:trips = [[2,1,5],[3,5,7]], capacity = 3
输出:true

示例 4:

输入:trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11
输出:true

提示:

  1. 你可以假设乘客会自觉遵守 “先下后上” 的良好素质
  2. trips.length <= 1000
  3. trips[i].length == 3
  4. 1 <= trips[i][0] <= 100
  5. 0 <= trips[i][1] < trips[i][2] <= 1000
  6. 1 <= capacity <= 100000

解题思路

首先想到的解法是通过区间合并,具体做法如下

  • 先合并首位项是相同数的区间,合并后的区间的乘客数量为两个区间乘客数量的最大值
  • 合并重叠区间,重叠区间的乘客数量为两个区间乘客数量的和

但是第一步就碰到了问题,我们很难快速的解。所以这种做法pass。

接着我们发现0 <= trips[i][1] < trips[i][2] <= 1000,所以不难想到建立一个1001大小的数组,然后遍历trips,将区间内的数加到建立的数组中,例如,对于例1我们先加入第一个区间[2, 1, 5]

0 2 2 2 2 2 0 0 0 0...

接着加入第二个区间[3, 3, 7]得到

0 2 2 5 5 5 3 3 0 0...

最后求出区间的最大值,看最大值是不是小于capacity即可。

class Solution:
    def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
        tmp = [0]*1001
        for item in trips:
            for i in range(item[1], item[2]):
                tmp[i] += item[0]
        return max(tmp) <= capacity

当然上面这种写法可以进一步优化,我们可以对每个区间的两个端点标记,标记的时候使用了trick,左边端点使用加法(表示有人上车),右边端点使用减法(表示有人下车)。最后遍历标记后的数组,遍历的过程了累加标记值,如果超过了capacity,那么就表示车上的人数过多了。

class Solution:
    def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
        tmp = [0]*1001
        for item in trips:
            tmp[item[1]] += item[0]
            tmp[item[2]] -= item[0]
            
        for i in tmp:
            capacity -= i
            if capacity < 0:
                return False
        return True

那如果区间的范围不是[0,1000],非常大怎么办?实际上这题和Leetcode 253:Meeting Rooms II(超详细的解法!!!)非常类似,直接拿来使用即可

class Solution:
    def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
        if not trips:
            return 0
        tmp = sorted(x for v, i, j in trips for x in [[i, v], [j, -v]])
        
        n = 0
        for _, v in tmp:
            n += v
            if n > capacity:
                return False
        return True

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值