[算法]时间分隔

时间分隔

问题地址

题目描述

Description

Given arrival and departure times of all trains that reach a railway station. Your task is to find the minimum number of platforms required for the railway station so that no train waits.

Note: Consider that all the trains arrive on the same day and leave on the same day. Also, arrival and departure times must not be same for a train.

Input

The first line of input contains T, the number of test cases. For each test case, first line will contain an integer N, the number of trains. Next two lines will consist of N space separated time intervals denoting arrival and departure times respectively.

Note: Time intervals are in the 24-hourformat(hhmm), preceding zeros are insignificant. 200 means 2:00.
Consider the example for better understanding of input.

Constraints:1 <= T <= 100,1 <= N <= 1000,1 <= A[i] < D[i] <= 2359

Output

For each test case, print the minimum number of platforms required for the trains to arrive and depart safely.

Sample Input 1

1
6 
900  940 950  1100 1500 1800
910 1200 1120 1130 1900 2000

Sample Output 1

3
题目解析

一共有n个火车,每个火车有其到达和离开的时间,求最小站台数,可以保证所有的火车都可以正常运转

第一行是火车到达时间,第二行是火车离开时间,不要被用例格式迷惑

  1. 每辆火车来之前,站台上不允许有火车
  2. 火车的到达和离开时间不能相同
  3. 为了让所有的火车都可以来,求最小的站台数量
  4. 火车的进站时间的有序的

注意:

  1. 用例之间的空格数量,有的是两个空格,有的是一个空格
思路解析

思路1: 贪心,复杂度O(N)

每次遍历一次火车数组,每次确定一个站台,尽可能让更多的火车通过,直到数组中所有元素全部遍历过了为止

注意:

​ 如果直接按照这种思路去遍历数组的话,复杂度一定不是最优的,因为每次只确定一个站台,需要多次遍历原数组才能确定所有站台

优化:

​ 在原有遍历上增加一个数组用于维护站台的信息,数组的个数代表站台的数量,数组的元素值代表着最后一趟火车离开的时间

​ 如果需要增加站台就添加元素,否则就更新数组中的元素,

​ eg:

驶入: 900  940 950  1100 1500 1800
离开: 910 1200 1120 1130 1900 2000

init 
list =[-1] 有一个站台,没有火车来

900>-1,允许火车进入,更新list =[910] 第一个火车进入第一个站台
940>910,允许火车进入,更新list =[1200] 第二个火车进入第一个站台
950<1200,无法进入,创建新的站台,更新list=[1200,1120] 第三个火车进入第二个站台
1100<所有元素,无法进入,创建新的站台,更新list=[1200,1120,1130] 第四个火车进入第三个站台
1500>1200,允许火车进入,更新list=[1900,1120,1130] 第五个火车进入第一个站台
1800>1120,允许火车进入,更新list=[1900,2000,1130] 第五个火车进入第一个站台

思路2 ,遍历复杂度O(N),排序复杂度O(NlogN),如果不排序的话需要O(N2)的复杂度

这道题其实是求最大的交叉的点的个数

在这里插入图片描述

中间最长的部分有三个点交叉,因此答案就是3

那么如何去求呢?

一种方式是用每个火车的出发时间去和其余火车的其实时间去比较,如果在其后面,那么交叉个数加1,比如1200在950的后面

另一种是排序后比较

代码实现

思路一:python

if __name__ == '__main__':
    for i in range(int(input())):
        n = int(input())
        in_arr = list(map(int, filter(lambda x: x != "", input().split(" "))))
        out_arr = list(map(int, filter(lambda x: x != "", input().split(" "))))
        train_arr = list(zip(in_arr, out_arr)) 
        # sorted(train_arr)  #根据进站时间对所有火车排序 不用排序,本题有序
        plat_arr = [-1]  # 初始一个进站口
        for x in train_arr:
            is_new_plat = True # 是否创建新的站台
            for i in range(len(plat_arr)):
                if x[0] > plat_arr[i]:  # 遍历所有的进站口,如果进站时间大于了出站时间,就允许进站
                    plat_arr[i] = x[1]  # 更新该进站口的出站时间
                    is_new_plat = False
                    break
            if is_new_plat:
                plat_arr.append(x[1])  # 如果所有进站口都不允许进站,就创建一个新的进站口,允许其进站
        print(len(plat_arr))

思路2:java

import java.io.*;
import java.util.*;

class Main {
	public static void main (String[] args) {
		Scanner s=new Scanner(System.in);
		int t=s.nextInt();
		while(t>0){
		    int n=s.nextInt();
		    int[]arr=new int[n];
		    int[]dept=new int[n];
		    for(int i=0;i<n;i++)
		    arr[i]=s.nextInt();
		    for(int i=0;i<n;i++)
		    dept[i]=s.nextInt();
		    
		    System.out.println(compute(arr,dept,n));
		    t--;
		}
	}
	public static int compute(int[]arr,int[]dept,int n){
	    int max=1,curr=1;
	    Arrays.sort(arr);
	    Arrays.sort(dept);
	    int i=1,j=0;
	    while(i<n&&j<n){
	        if(arr[i]<dept[j]){
	            curr++;
	            if(curr>max)
	            max=curr;
	            i++;
	        }else{
	            curr--;
	            j++;
	        }
	    }
	    return max;
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值