1396. 设计地铁系统

目录

地铁系统乘客出行时间统计 — 设计并实现 UndergroundSystem 类

题目描述

解题分析

解题方法

代码实现(Python)

示例说明

复杂度分析

优缺点分析与扩展

优点

可能的不足

扩展

总结


地铁系统乘客出行时间统计 — 设计并实现 UndergroundSystem 类

题目描述

在一个地铁系统中,我们想跟踪乘客从不同车站出发,到达另一车站所花费的时间,并计算两站之间的平均出行时间。实现一个类 UndergroundSystem,支持以下操作:

  • checkIn(int id, string stationName, int t)
    乘客 ID 为 id,在时间 t 从车站 stationName 进入地铁。一个乘客在任意时刻只会有一个“进站”记录。
  • checkOut(int id, string stationName, int t)
    乘客 ID 为 id,在时间 t 从车站 stationName 离开地铁。
  • getAverageTime(string startStation, string endStation)
    返回所有从 startStation 进入且到达 endStation 离开的乘客的平均出行时间。

要求:

  • 时间 t 是严格递增的,即每位乘客的出站时间一定大于进站时间。
  • 对于每对起止站点,能够多次查询平均时间。
  • 可以假设所有操作调用都是合理的,比如每个乘客的 checkIncheckOut 都成对出现且时序正确。

解题分析

核心需求是实时记录每个乘客的行程开始时间和起点车站,以及统计从一个车站到另一个车站的所有行程总时间和次数,以便计算平均时间。

需要两个核心数据结构:

  1. 乘客进站信息映射
    用于记录每个乘客的进站站点和时间,方便在乘客出站时计算行程时长。
  2. 行程时间统计映射
    用于累加从某站到另一站的所有行程的总时间及次数,支持计算平均时间。

解题方法

  1. 记录进站
    乘客进站时,存储 (id) -> (stationName, t),表示乘客 ID、进站车站及时间。
  2. 计算并更新出站数据
    乘客出站时,根据乘客 ID 查找其进站信息,计算行程时间 t_out - t_in,更新该线路(起点到终点)的累计时间和计数。
  3. 获取平均时间
    根据起点和终点站查询累计总时间和次数,计算平均时间返回。

这种设计实现逻辑清晰,且能高效支持多次查询。


代码实现(Python)

class UndergroundSystem:
    def __init__(self):
        # 乘客进站记录:id -> (stationName, time)
        self.check_in_map = {}
        # 线路累计数据:(startStation, endStation) -> [total_time, trip_count]
        self.travel_map = {}

    def checkIn(self, id: int, stationName: str, t: int) -> None:
        self.check_in_map[id] = (stationName, t)

    def checkOut(self, id: int, stationName: str, t: int) -> None:
        start_station, start_time = self.check_in_map.pop(id)
        route_key = (start_station, stationName)
        travel_time = t - start_time
        if route_key not in self.travel_map:
            self.travel_map[route_key] = [0, 0]
        self.travel_map[route_key][0] += travel_time
        self.travel_map[route_key][1] += 1

    def getAverageTime(self, startStation: str, endStation: str) -> float:
        total_time, count = self.travel_map[(startStation, endStation)]
        return total_time / count

示例说明

假设我们有以下操作:

undergroundSystem = UndergroundSystem()
undergroundSystem.checkIn(1, "A", 3)       # 乘客1在时间3从车站A进站
undergroundSystem.checkOut(1, "B", 8)      # 乘客1在时间8从车站B出站,行程时间5
print(undergroundSystem.getAverageTime("A", "B"))  # 输出5.0

undergroundSystem.checkIn(2, "A", 10)
undergroundSystem.checkOut(2, "B", 15)     # 乘客2行程时间5
print(undergroundSystem.getAverageTime("A", "B"))  # 输出(5+5)/2=5.0

undergroundSystem.checkIn(3, "A", 20)
undergroundSystem.checkOut(3, "B", 30)     # 乘客3行程时间10
print(undergroundSystem.getAverageTime("A", "B"))  # 输出(5+5+10)/3=6.67

这展示了如何累计多条路线数据,并返回平均值。


复杂度分析

  • checkIn
    时间复杂度为 O(1),直接插入哈希表。
  • checkOut
    时间复杂度为 O(1),读取进站信息、更新累计信息均为哈希表操作。
  • getAverageTime
    时间复杂度为 O(1),直接通过哈希表获取统计数据并计算。

空间复杂度主要取决于乘客的最大同时进站数量和路线对数量。


优缺点分析与扩展

优点

  • 简单易实现,数据结构清晰。
  • 支持高效多次查询平均时间。
  • 代码结构直观,容易维护。

可能的不足

  • 当乘客数目或路线数非常大时,存储空间消耗较大。
  • 统计是累加统计,无法提供更多统计信息(如中位数等)。

扩展

  • 可以扩展支持删除某条数据,或更新某些行程。
  • 可以优化统计结构,支持更多统计指标。
  • 结合时间窗口,支持统计不同时间段的平均时间。

总结

本题考察了设计合适的数据结构进行动态统计的能力。
通过两个哈希表分别维护乘客状态和线路统计,能够高效实现需求。
Python 实现简洁明了,符合面试和实际系统设计的要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值