在问 · 算法题解

1094. 拼车

中等栈与堆差分数组力扣原题 ↗

题目描述

一辆车最开始有 capacity 个空座位,只能一路向东开,不能掉头。

输入整数 capacity 和数组 trips。其中第 i 项为 [numPassengersi, fromi, toi],意思是有 numPassengersi 位乘客要在距起点 fromi 公里处上车、在 toi 公里处下车。

在同一地点,先让到站的乘客下车,再让新乘客上车。行驶途中任何时刻车上人数都不能超过 capacity。能接送完所有乘客返回 true,否则返回 false。

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

解释:在 3 到 5 公里之间车上有 2 + 3 = 5 人,超过 4 个座位。

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

解释:最多同时 5 人,正好不超过座位数。

数据范围

  • 1 <= trips.length <= 1000
  • trips[i].length == 3
  • 1 <= numPassengersi <= 100
  • 0 <= fromi < toi <= 1000
  • 1 <= capacity <= 10^5

解题思路:差分数组

位置只有 0–1000,可以用差分数组。每段行程在上车点 diff[from] += num,在下车点 diff[to] -= num。然后从西向东累加,前缀和 cur 就是车开过该位置时车上的人数,只要某处 cur > capacity 就返回 false。先加上车、再减下车在同一个 diff 格子里合并完成,恰好体现“先下后上”。

为什么正确

处理完位置 p 后,cur = diff[0] + ... + diff[p] = 从 p 开往 p+1 时车上的乘客数。

复杂度分析

时间 O(n + 1001),空间 O(1001)。

易错点

乘客在 to 位置已经下车,所以行程占用的是半开区间 [from, to),减法要写在 diff[to] 而不是 diff[to+1],否则 [[2,1,5],[3,5,7]] capacity=3 会被错误判为超载。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
        diff = [0] * 1001
        for num, a, b in trips:
            diff[a] += num
            diff[b] -= num
        cur = 0
        for d in diff:
            cur += d
            if cur > capacity:
                return False
        return True

载入编辑器,自己跑一遍 →

其他解法

两种方法的核心都是“在端点记录变化量再累加”。差分数组把变化量按下标放在数组里,适合位置范围小的情况;事件排序只处理真正出现的端点,适合位置范围大或不是整数的情况。

解法 2:事件排序扫描线 时间 O(n log n),空间 O(n)

把每段行程拆成两个事件:在上车点乘客增加 num,在下车点乘客减少 num。按位置排序,位置相同时先处理下车(变化量为负的排在前面),因为在同一点下车的乘客会先让出座位。按顺序累加变化量,任何时刻超过座位数就返回 false。

复杂度只和行程数量有关,位置范围很大(如 10^9)时依然适用。本题位置不超过 1000,排序反而比差分数组多一个 log 因子。

class Solution:
    def carPooling(self, trips: List[List[int]], capacity: int) -> bool:
        events = []
        for num, a, b in trips:
            events.append((a, num))
            events.append((b, -num))
        events.sort()
        cur = 0
        for _, delta in events:
            cur += delta
            if cur > capacity:
                return False
        return True

栈与堆 专题的其他题目

查看 栈与堆 全部题目 →