1904、拼车

假设你是一位顺风车司机,车上最初有 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. trips.length <= 1000
  2. trips[i].length == 3
  3. 1 <= trips[i][0] <= 100
  4. 0 <= trips[i][1] < trips[i][2] <= 1000
  5. 1 <= capacity <= 100000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/car-pooling
 

解题思路:

  1. 冲着标签“贪心”做的,这个真的是贪心吗?或者说是我理解不够深刻?做完之后看了一下评论,貌似我的做法和其中的map有点像?鉴于我还不知道什么是map,这里又是一个坑,看完map之后回来填充。
  2. 定义一个数组,遍历一次输入的数据,把每个站点上、下客人数直接存到数组里
  3. 遍历一次站点,计算经过每个站点之后,车上的人数,如果人数大于可乘坐数量,直接返回false即可。

 

做题过程中遇到的问题:

  1.  相同的测试用例,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;
}

 

试图改进:

  1. 直接定义了一个最大范围的数组,如果使用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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值