题目描述
请你实现一个类 UndergroundSystem
,它支持以下 3 种方法:
checkIn(int id, string stationName, int t)
- 编号为
id
的乘客在t
时刻进入地铁站stationName
。 - 一个乘客在同一时间只能在一个地铁站进入或者离开。
- 编号为
checkOut(int id, string stationName, int t)
- 编号为
id
的乘客在t
时刻离开地铁站stationName
。
- 编号为
getAverageTime(string startStation, string endStation)
- 返回从地铁站
startStation
到地铁站endStation
的平均花费时间。 - 平均时间计算的行程包括当前为止所有从
startStation
直接到达endStation
的行程。 - 调用
getAverageTime
时,询问的路线至少包含一趟行程。
- 返回从地铁站
你可以假设所有对 checkIn
和 checkOut
的调用都是符合逻辑的。也就是说,如果一个顾客在 t1 时刻到达某个地铁站,那么他离开的时间 t2
一定满足 t2 > t1
。所有的事件都按时间顺序给出。
样例
输入:
["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","checkOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","getAverageTime"]
[[],[45,"Leyton",3],[32,"Paradise",8],[27,"Leyton",10],[45,"Waterloo",15],[27,"Waterloo",20],[32,"Cambridge",22],["Paradise","Cambridge"],["Leyton","Waterloo"],[10,"Leyton",24],["Leyton","Waterloo"],[10,"Waterloo",38],["Leyton","Waterloo"]]
输出:
[null,null,null,null,null,null,null,14.0,11.0,null,11.0,null,12.0]
解释:
UndergroundSystem undergroundSystem = new UndergroundSystem();
undergroundSystem.checkIn(45, "Leyton", 3);
undergroundSystem.checkIn(32, "Paradise", 8);
undergroundSystem.checkIn(27, "Leyton", 10);
undergroundSystem.checkOut(45, "Waterloo", 15);
undergroundSystem.checkOut(27, "Waterloo", 20);
undergroundSystem.checkOut(32, "Cambridge", 22);
undergroundSystem.getAverageTime("Paradise", "Cambridge");
// 返回 14.0。从 "Paradise"(时刻 8)到 "Cambridge"(时刻 22)的行程只有一趟
undergroundSystem.getAverageTime("Leyton", "Waterloo");
// 返回 11.0。
总共有 2 躺从 "Leyton" 到 "Waterloo" 的行程,编号为 id=45 的乘客出发于 time=3 到达于 time=15;
编号为 id=27 的乘客出发于 time=10 到达于 time=20。所以平均时间为 ( (15-3) + (20-10) ) / 2 = 11.0
undergroundSystem.checkIn(10, "Leyton", 24);
undergroundSystem.getAverageTime("Leyton", "Waterloo");
// 返回 11.0
undergroundSystem.checkOut(10, "Waterloo", 38);
undergroundSystem.getAverageTime("Leyton", "Waterloo");
// 返回 12.0
限制
- 总共最多有
20000
次操作。 1 <= id, t <= 10^6
- 所有的字符串包含大写字母,小写字母和数字。
1 <= stationName.length <= 10
- 与标准答案误差在
10^-5
以内的结果都视为正确结果。
算法
(哈希表) 插入 $O(1)$;查询 $O(1)$。
- 进站的时候,记录这个人的站名和时间。
- 出站的时候,直接在哈希表中累加这个人所用的时间,以及记录有多少个这样的信息。
- 查询的时候直接求平均输出结果。
时间复杂度
- 所有操作都只需要常数的时间复杂度。
空间复杂度
- 总共需要额外 $O(n)$ 的空间。
C++ 代码
class UndergroundSystem {
public:
unordered_map<int, pair<string, int>> in;
unordered_map<string, unordered_map<string, pair<double, int>>> ans;
UndergroundSystem() {
}
void checkIn(int id, string stationName, int t) {
in[id] = make_pair(stationName, t);
}
void checkOut(int id, string stationName, int t) {
ans[in[id].first][stationName].first += t - in[id].second;
ans[in[id].first][stationName].second++;
}
double getAverageTime(string startStation, string endStation) {
return ans[startStation][endStation].first / ans[startStation][endStation].second;
}
};
/**
* Your UndergroundSystem object will be instantiated and called as such:
* UndergroundSystem* obj = new UndergroundSystem();
* obj->checkIn(id,stationName,t);
* obj->checkOut(id,stationName,t);
* double param_3 = obj->getAverageTime(startStation,endStation);
*/