假设你是一位顺风车司机,车上最初有 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
提示:
你可以假设乘客会自觉遵守 “先下后上” 的良好素质
- trips.length <= 1000
- trips[i].length == 3
- 1 <= trips[i][0] <= 100
- 0 <= trips[i][1] < trips[i][2] <= 1000
- 1 <= capacity <= 100000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/car-pooling
解题思路:
- 冲着标签“贪心”做的,这个真的是贪心吗?或者说是我理解不够深刻?做完之后看了一下评论,貌似我的做法和其中的map有点像?鉴于我还不知道什么是map,这里又是一个坑,看完map之后回来填充。
- 定义一个数组,遍历一次输入的数据,把每个站点上、下客人数直接存到数组里
- 遍历一次站点,计算经过每个站点之后,车上的人数,如果人数大于可乘坐数量,直接返回false即可。
做题过程中遇到的问题:
- 相同的测试用例,VS2017上输出正确,放到LeetCode上运行就不对了,问题在于函数的形参int** trips。
具体情况见下方的实例代码int test_function(int **array) { //在VS中,如果要使用 test_array[2][2],直接写array[2][2]会报错 //应该是因为对于函数来说,array只是指向了一个地址,不知道这个是几阶指针 //所以我写成了 ((int*)array + 2*3)[2] ,即在原地址的基础上偏移之后,再去当一维数组使用 //但是在LeetCode中,需要直接写成 array[2][2] //((int*)array + 2*3)[2] 这个形式,在LeetCode中会导致越界,从而导致输出结果不对 //至于在LeetCode中 ((int*)array + 2*3)[2] 最终指向何处,暂时不了解 //C不支持playground调试 } int main(void) { int test_array[3][3] = {0} test_function(test_array); return 0; }
最终提交代码:
执行用时 :12 ms, 在所有 C 提交中击败了88.83%的用户
内存消耗 :7.5 MB, 在所有 C 提交中击败了45.28%的用户
(如果需要在VS2017上运行,需要把 trips[i][1] 调整为 ((int*)trips + 3 * i)[1] ,其它也做相应调整,另外版本的VS不清楚)
bool carPooling(int** trips, int tripsSize, int* tripsColSize, int capacity)
{
int per_trip_size[1001][2] = { 0 }; //每个站点的上下客人数 [0]下客 [1]上客
int destination = 0;
int station_in = 0, station_out = 0, passenger_num = 0;;
for (int i = 0; i < tripsSize; i++)
{
station_in = trips[i][1] ; //上客站点
station_out = trips[i][2]; //下客站点
passenger_num = trips[i][0]; //变动乘客人数
//记录使用到的终点
destination = station_out > destination ? station_out : destination;
per_trip_size[station_out][0] += passenger_num; //记录在该站点下车的人数
per_trip_size[station_in][1] += passenger_num; //记录在该站点上车的人数
}
int passengers = 0;
for (int i = 0; i <= destination; i++)
{
passengers -= per_trip_size[i][0];
passengers = passengers < 0 ? 0 : passengers;
passengers += per_trip_size[i][1];
if (passengers > capacity)
return false;
}
return true;
}
试图改进:
- 直接定义了一个最大范围的数组,如果使用malloc之类的进行动态内存分配,是否可以降低内存消耗?时间上会如何?尝试一下。
改成了动态分配的形式,VS上运行OK,但是在LeetCode上运行通不过,why?
才发现没有free掉,暂时不改了
bool carPooling(int** trips, int tripsSize, int* tripsColSize, int capacity)
{
// [0][n] 上 [1][n] 下
int **per_trip_size = (int*)malloc(sizeof(int*) * 2);
per_trip_size[0] = (int*)malloc(sizeof(int));
per_trip_size[1] = (int*)malloc(sizeof(int));
int destination = 0;
int station_in = 0, station_out = 0, passenger_num = 0;;
for (int i = 0; i < tripsSize; i++)
{
passenger_num = trips[i][0]; //变动乘客人数
station_in = trips[i][1] ; //上客站点
station_out = trips[i][2]; //下客站点
if (station_out > destination)
{
destination = station_out;
per_trip_size[0] = (int*)realloc(per_trip_size[0], destination *
sizeof(int));
per_trip_size[1] = (int*)realloc(per_trip_size[1], destination *
sizeof(int));
}
per_trip_size[0][station_in] += passenger_num; //记录在该站点上车的人数
per_trip_size[1][station_out] += passenger_num; //记录在该站点下车的人数
}
int passengers = 0;
for (int i = 0; i <= destination; i++)
{
passengers -= per_trip_size[1][i];
passengers = passengers < 0 ? 0 : passengers;
passengers += per_trip_size[0][i];
if (passengers > capacity)
return false;
}
return true;
}