作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode-cn.com/problems/car-pooling/

题目描述

假设你是一位顺风车司机,车上最初有 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

题目大意

有一辆车,在一个单向的路上行驶。给定了很多区间,每个区间都表示了这段区间上来的人数、上来的地点、下车的地点。已知车的容积,判断能否在路径中能装下所有的人。

解题方法

本身这个题让我们判断路径中的最大人数是否超过车的装载能力。那么直觉的思路是:把每个区间的人数变化,求解到坐标系每个点上,最后求所有点中最大的人数。

但是这样的话,时间复杂度是

O

(

M

N

)

O(MN)

O(MN),即区间个数*区间大小。 当区间个数比较多、区间比较大的时候,会超时。

本题利用了一个很巧妙的方法:差分数组

差分数组

何为差分数组?不要被这个名字给吓到了,其实道理很简单。知道前缀和么?前缀和

p

r

e

S

u

m

[

i

]

preSum[i]

preSum[i] 就是

s

u

m

(

0..

i

)

sum(0..i)

sum(0..i)。而差分数组的每个位置的值就是

n

u

m

s

[

i

]

n

u

m

s

[

i

1

]

nums[i] - nums[i - 1]

nums[i]−nums[i−1],即每个位置与前面位置的差。

这有啥用呢?当我们知道了数组的起始值,然后知道了每个位置和前面位置的差,那么通过累加差分数组,就可以恢复出原始的数组值。

那么查分数组能起到什么用呢?当我们把差分数组的

i

i

i 位置

+

x

+ x

+x,那么当累加差分数组恢复原始数组时,就相当于恢复出的原始数组从

i

i

i 位置向后的所有元素都

+

x

+x

+x。

那如果题目给出的是个区间,表示把一个区间里面把所有位置都

+

x

+x

+x 怎么办呢?可以在差分数组区间开始的地方

+

x

+x

+x,在差分数组区间结束的后一个元素

x

-x

−x,于是在还原数组的时候,就相当于只把 区间内的所有值

+

x

+x

+x。

比如,想给

n

u

m

s

[

1..3

]

nums[1..3]

nums[1..3] 内所有的元素都

+

3

+3

+3,那么只用给差分数组

d

i

f

f

[

1

]

+

3

diff[1] + 3

diff[1]+3,给

d

i

f

f

[

4

]

3

diff[4] - 3

diff[4]−3。

  • 注意是给

    d

    i

    f

    f

    [

    4

    ]

    diff[4]

    diff[4],而不是

    d

    i

    f

    f

    [

    3

    ]

    diff[3]

    diff[3],因为我们要给

    n

    u

    m

    s

    [

    3

    ]

    nums[3]

    nums[3]也要

    +

    3

    +3

    +3。

对于本题,其实就是一个初始时全为 0 的

n

u

m

s

nums

nums 数组,对其指定的区间内所有数字都加上

c

a

p

a

c

i

t

y

[

0

]

capacity[0]

capacity[0]。

  • 注意本题的区间相当于左闭右开:即上车点

    c

    a

    p

    a

    c

    i

    t

    y

    [

    1

    ]

    capacity[1]

    capacity[1] 位置需要加上

    c

    a

    p

    a

    c

    i

    t

    y

    [

    0

    ]

    capacity[0]

    capacity[0],而下车点

    c

    a

    p

    a

    c

    i

    t

    y

    [

    1

    ]

    capacity[1]

    capacity[1] 就需要减去

    c

    a

    p

    a

    c

    i

    t

    y

    [

    0

    ]

    capacity[0]

    capacity[0]。原因是「乘客会自觉遵守 “先下后上” 的良好素质」,所以到了下车点的时候,到站的乘客立马下去了,就不占用位置了。

最终,我们要判断的是:当还原每个点的人数的时候,需要保证此点的人数不会大于

c

a

p

a

c

i

t

y

capacity

capacity。

代码

在下面的代码中,我直接初始化了长度为 1010 的路径差分数组,是因为题目给出的数据在 1000 以内。

首先根据

t

r

i

p

s

trips

trips,初始化该差分数组:

  • road[trip[1]] += trip[0]; 即在 trip[1] 的位置上车 trip[0] 个人。
  • road[trip[2]] -= trip[0]; 即在 trip[2] 的位置下车 trip[0] 个人。

在完成差分数组的初始化之后,需要还原每个位置的人数,即

c

u

r

cur

cur。遍历并累加差分数组中的每个元素,就得到了路径中每个点的人数。如果该点的人数

c

u

r

>

c

a

p

a

c

i

t

y

cur > capacity

cur>capacity,那么说明超出了车的人数限制,需要返回 false。

当累加完了所有的位置,发现都每个位置的

c

u

r

<

=

c

a

p

a

c

i

t

y

cur <= capacity

cur<=capacity,则返回 true.

C++ 代码如下:

class Solution {
public:
bool carPooling(vector<vector<int>>& trips, int capacity) {
vector<int> road(1010, 0);
for (vector<int>& trip : trips) {
road[trip[1]] += trip[0];
road[trip[2]] -= trip[0];
}
int cur = 0;
for (int i = 0; i < 1009; i ++) {
cur += road[i];
if (cur > capacity) {
return false;
}
}
return true;
}
};

参考资料:https://www.yuque.com/docs/share/a07ed436-527b-478c-b3aa-bb72dae94f88

日期

2021 年 8 月 21 日 —— 入职新公司了

【LeetCode】1094. Car Pooling 拼车的更多相关文章

  1. LeetCode 1094. Car Pooling

    原题链接在这里:https://leetcode.com/problems/car-pooling/ 题目: You are driving a vehicle that has capacity e ...

  2. HDU 4526 拼车记

    话说威威猫有一次去参加比赛,虽然学校离比赛地点不太远,但威威猫还是想坐出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人坐车去,还是一堆人一起,总共需要支付的钱是一样的(每辆出租 ...

  3. dp 洛谷P1977 出租车拼车 线性dp

    题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆人一起,总共需要支付的钱 ...

  4. hdoj 4526 威威猫系列故事——拼车记

    威威猫系列故事——拼车记 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  5. 拼车专用道 HOV lane

    近几年,不少人开始找人拼车上下班,这样不仅能减少车辆开支,同时也能为缓解交通拥堵贡献一份力量.在国外,不少城市都在交通高峰时段为这一类车辆开设专用车道,叫做HOV lane.

  6. P1977 出租车拼车(DP)

    题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆人一起,总共需要支付的钱 ...

  7. 洛谷——P1977 出租车拼车

    题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆人一起,总共需要支付的钱 ...

  8. 洛谷—— P1977 出租车拼车

    https://www.luogu.org/problem/show?pid=1977 题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总 ...

  9. P1977 出租车拼车

    P1977 出租车拼车 题目背景 话说小 x 有一次去参加比赛,虽然学校离比赛地点不太远,但小 x 还是想坐 出租车去.大学城的出租车总是比较另类,有“拼车”一说,也就是说,你一个人 坐车去,还是一堆 ...

随机推荐

  1. intent.getSerializableExtra(转)

    Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short ...

  2. WPS for Linux 字体配置(字体缺失解决办法)

    WPS for Linux 字体配置(字体缺失解决办法) 1. 背景 有些linux装完wps后提示"部分字体无法显示"或"some formula symbols mi ...

  3. 1D RKDG to shallow water equations

    RKDG to shallow water equations 1.Governing Equations \[\frac{\partial U}{\partial t} + \frac{\parti ...

  4. android 点击图片从Fragment跳转到activity

    android 点击图片从Fragment跳转到activity 在Fragment里编写 public View onCreateView(@NonNull LayoutInflater infla ...

  5. Notepad++—设置背景颜色

    之前,编程一直用的都是黑色背景色,最近发现,黑色背景色+高光字体,时间久了对眼睛特别不好.感觉自己编程到现在几年时间,眼睛就很不舒服,甚至有青光眼的趋势.所以,改用白底黑字,即"日间模式&q ...

  6. No.1 R语言在生物信息中的应用——序列读取及格式化输出

    目的:读入序列文件(fasta格式),返回一个数据框,内容包括--存储ID.注释行(anno).长度(len).序列内容(content) 一.问题思考: 1. 如何识别注释行和序列内容行 2. 如何 ...

  7. 基于 Helm 快速部署 Wordpress

    Helm 是 Kubernetes 中的一个开源软件包管理工具,Rainbond 从 5.3.1 版本开始支持部署 Helm 应用.实现 Helm 应用的便捷部署,访问控制.使 Rainbond 用户 ...

  8. 文件和目录之间建立链接 (ln)

  9. ES6必知,箭头函数与普通函数的区别。

    1. 箭头函数没有prototype(原型),所以箭头函数本身没有this let a = () =>{}; console.log(a.prototype); // undefined 2. ...

  10. C语言time函数获取当前时间

    以前放了个链接,但是原作者把博文删了,这里放一个获取时间的代码,已经比较详细所以不做注释 #include<stdio.h> #include<time.h> #include ...