{ "data": { "question": { "questionId": "1512", "questionFrontendId": "1396", "categoryTitle": "Algorithms", "boundTopicId": 170711, "title": "Design Underground System", "titleSlug": "design-underground-system", "content": "
An underground railway system is keeping track of customer travel times between different stations. They are using this data to calculate the average time it takes to travel from one station to another.
\n\nImplement the UndergroundSystem
class:
void checkIn(int id, string stationName, int t)
\n\n\tid
, checks in at the station stationName
at time t
.void checkOut(int id, string stationName, int t)
\n\tid
, checks out from the station stationName
at time t
.double getAverageTime(string startStation, string endStation)
\n\tstartStation
to endStation
.startStation
to endStation
that happened directly, meaning a check in at startStation
followed by a check out from endStation
.startStation
to endStation
may be different from the time it takes to travel from endStation
to startStation
.startStation
to endStation
before getAverageTime
is called.You may assume all calls to the checkIn
and checkOut
methods are consistent. If a customer checks in at time t1
then checks out at time t2
, then t1 < t2
. All events happen in chronological order.
\n
Example 1:
\n\n\nInput\n["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","checkOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","getAverageTime"]\n[[],[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"]]\n\nOutput\n[null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00000]\n\nExplanation\nUndergroundSystem undergroundSystem = new UndergroundSystem();\nundergroundSystem.checkIn(45, "Leyton", 3);\nundergroundSystem.checkIn(32, "Paradise", 8);\nundergroundSystem.checkIn(27, "Leyton", 10);\nundergroundSystem.checkOut(45, "Waterloo", 15); // Customer 45 "Leyton" -> "Waterloo" in 15-3 = 12\nundergroundSystem.checkOut(27, "Waterloo", 20); // Customer 27 "Leyton" -> "Waterloo" in 20-10 = 10\nundergroundSystem.checkOut(32, "Cambridge", 22); // Customer 32 "Paradise" -> "Cambridge" in 22-8 = 14\nundergroundSystem.getAverageTime("Paradise", "Cambridge"); // return 14.00000. One trip "Paradise" -> "Cambridge", (14) / 1 = 14\nundergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.00000. Two trips "Leyton" -> "Waterloo", (10 + 12) / 2 = 11\nundergroundSystem.checkIn(10, "Leyton", 24);\nundergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.00000\nundergroundSystem.checkOut(10, "Waterloo", 38); // Customer 10 "Leyton" -> "Waterloo" in 38-24 = 14\nundergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 12.00000. Three trips "Leyton" -> "Waterloo", (10 + 12 + 14) / 3 = 12\n\n\n
Example 2:
\n\n\nInput\n["UndergroundSystem","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime"]\n[[],[10,"Leyton",3],[10,"Paradise",8],["Leyton","Paradise"],[5,"Leyton",10],[5,"Paradise",16],["Leyton","Paradise"],[2,"Leyton",21],[2,"Paradise",30],["Leyton","Paradise"]]\n\nOutput\n[null,null,null,5.00000,null,null,5.50000,null,null,6.66667]\n\nExplanation\nUndergroundSystem undergroundSystem = new UndergroundSystem();\nundergroundSystem.checkIn(10, "Leyton", 3);\nundergroundSystem.checkOut(10, "Paradise", 8); // Customer 10 "Leyton" -> "Paradise" in 8-3 = 5\nundergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.00000, (5) / 1 = 5\nundergroundSystem.checkIn(5, "Leyton", 10);\nundergroundSystem.checkOut(5, "Paradise", 16); // Customer 5 "Leyton" -> "Paradise" in 16-10 = 6\nundergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.50000, (5 + 6) / 2 = 5.5\nundergroundSystem.checkIn(2, "Leyton", 21);\nundergroundSystem.checkOut(2, "Paradise", 30); // Customer 2 "Leyton" -> "Paradise" in 30-21 = 9\nundergroundSystem.getAverageTime("Leyton", "Paradise"); // return 6.66667, (5 + 6 + 9) / 3 = 6.66667\n\n\n
\n
Constraints:
\n\n1 <= id, t <= 106
1 <= stationName.length, startStation.length, endStation.length <= 10
2 * 104
calls in total to checkIn
, checkOut
, and getAverageTime
.10-5
of the actual value will be accepted.地铁系统跟踪不同车站之间的乘客出行时间,并使用这一数据来计算从一站到另一站的平均时间。
\n\n实现 UndergroundSystem
类:
void checkIn(int id, string stationName, int t)
\n\n\tid
的乘客,在时间 t
,从 stationName
站进入void checkOut(int id, string stationName, int t)
\n\tid
的乘客,在时间 t
,从 stationName
站离开double getAverageTime(string startStation, string endStation)
\n\tstartStation
站到 endStation
站的平均时间startStation
站 直接 到达 endStation
站的行程进行计算,也就是从 startStation
站进入并从 endStation
离开的行程startStation
到 endStation
的行程时间与从 endStation
到 startStation
的行程时间可能不同getAverageTime
之前,至少有一名乘客从 startStation
站到达 endStation
站你可以假设对 checkIn
和 checkOut
方法的所有调用都是符合逻辑的。如果一名乘客在时间 t1
进站、时间 t2
出站,那么 t1 < t2
。所有时间都按时间顺序发生。
示例 1:
\n\n\n输入\n[\"UndergroundSystem\",\"checkIn\",\"checkIn\",\"checkIn\",\"checkOut\",\"checkOut\",\"checkOut\",\"getAverageTime\",\"getAverageTime\",\"checkIn\",\"getAverageTime\",\"checkOut\",\"getAverageTime\"]\n[[],[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\"]]\n\n输出\n[null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00000]\n\n解释\nUndergroundSystem undergroundSystem = new UndergroundSystem();\nundergroundSystem.checkIn(45, \"Leyton\", 3);\nundergroundSystem.checkIn(32, \"Paradise\", 8);\nundergroundSystem.checkIn(27, \"Leyton\", 10);\nundergroundSystem.checkOut(45, \"Waterloo\", 15); // 乘客 45 \"Leyton\" -> \"Waterloo\" ,用时 15-3 = 12\nundergroundSystem.checkOut(27, \"Waterloo\", 20); // 乘客 27 \"Leyton\" -> \"Waterloo\" ,用时 20-10 = 10\nundergroundSystem.checkOut(32, \"Cambridge\", 22); // 乘客 32 \"Paradise\" -> \"Cambridge\" ,用时 22-8 = 14\nundergroundSystem.getAverageTime(\"Paradise\", \"Cambridge\"); // 返回 14.00000 。只有一个 \"Paradise\" -> \"Cambridge\" 的行程,(14) / 1 = 14\nundergroundSystem.getAverageTime(\"Leyton\", \"Waterloo\"); // 返回 11.00000 。有两个 \"Leyton\" -> \"Waterloo\" 的行程,(10 + 12) / 2 = 11\nundergroundSystem.checkIn(10, \"Leyton\", 24);\nundergroundSystem.getAverageTime(\"Leyton\", \"Waterloo\"); // 返回 11.00000\nundergroundSystem.checkOut(10, \"Waterloo\", 38); // 乘客 10 \"Leyton\" -> \"Waterloo\" ,用时 38-24 = 14\nundergroundSystem.getAverageTime(\"Leyton\", \"Waterloo\"); // 返回 12.00000 。有三个 \"Leyton\" -> \"Waterloo\" 的行程,(10 + 12 + 14) / 3 = 12\n\n\n
示例 2:
\n\n\n输入\n[\"UndergroundSystem\",\"checkIn\",\"checkOut\",\"getAverageTime\",\"checkIn\",\"checkOut\",\"getAverageTime\",\"checkIn\",\"checkOut\",\"getAverageTime\"]\n[[],[10,\"Leyton\",3],[10,\"Paradise\",8],[\"Leyton\",\"Paradise\"],[5,\"Leyton\",10],[5,\"Paradise\",16],[\"Leyton\",\"Paradise\"],[2,\"Leyton\",21],[2,\"Paradise\",30],[\"Leyton\",\"Paradise\"]]\n\n输出\n[null,null,null,5.00000,null,null,5.50000,null,null,6.66667]\n\n解释\nUndergroundSystem undergroundSystem = new UndergroundSystem();\nundergroundSystem.checkIn(10, \"Leyton\", 3);\nundergroundSystem.checkOut(10, \"Paradise\", 8); // 乘客 10 \"Leyton\" -> \"Paradise\" ,用时 8-3 = 5\nundergroundSystem.getAverageTime(\"Leyton\", \"Paradise\"); // 返回 5.00000 ,(5) / 1 = 5\nundergroundSystem.checkIn(5, \"Leyton\", 10);\nundergroundSystem.checkOut(5, \"Paradise\", 16); // 乘客 5 \"Leyton\" -> \"Paradise\" ,用时 16-10 = 6\nundergroundSystem.getAverageTime(\"Leyton\", \"Paradise\"); // 返回 5.50000 ,(5 + 6) / 2 = 5.5\nundergroundSystem.checkIn(2, \"Leyton\", 21);\nundergroundSystem.checkOut(2, \"Paradise\", 30); // 乘客 2 \"Leyton\" -> \"Paradise\" ,用时 30-21 = 9\nundergroundSystem.getAverageTime(\"Leyton\", \"Paradise\"); // 返回 6.66667 ,(5 + 6 + 9) / 3 = 6.66667\n\n\n
\n\n
提示:
\n\n1 <= id, t <= 106
1 <= stationName.length, startStation.length, endStation.length <= 10
次checkIn
、checkOut
和 getAverageTime
方法 2 * 104
10-5
以内的结果都被视为正确结果\\u7248\\u672c\\uff1a \\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528 \\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\"],\"java\":[\"Java\",\" \\u7248\\u672c\\uff1a \\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u88ab\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n \\u5305\\u542b Pair \\u7c7b: https:\\/\\/docs.oracle.com\\/javase\\/8\\/javafx\\/api\\/javafx\\/util\\/Pair.html <\\/p>\"],\"python\":[\"Python\",\" \\u7248\\u672c\\uff1a \\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982\\uff1aarray<\\/a>, bisect<\\/a>, collections<\\/a>\\u3002\\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n \\u6ce8\\u610f Python 2.7 \\u5c06\\u57282020\\u5e74\\u540e\\u4e0d\\u518d\\u7ef4\\u62a4<\\/a>\\u3002 \\u5982\\u60f3\\u4f7f\\u7528\\u6700\\u65b0\\u7248\\u7684Python\\uff0c\\u8bf7\\u9009\\u62e9Python 3\\u3002<\\/p>\"],\"c\":[\"C\",\" \\u7248\\u672c\\uff1a \\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528 \\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u60f3\\u4f7f\\u7528\\u54c8\\u5e0c\\u8868\\u8fd0\\u7b97, \\u60a8\\u53ef\\u4ee5\\u4f7f\\u7528 uthash<\\/a>\\u3002 \\\"uthash.h\\\"\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5bfc\\u5165\\u3002\\u8bf7\\u770b\\u5982\\u4e0b\\u793a\\u4f8b:<\\/p>\\r\\n\\r\\n 1. \\u5f80\\u54c8\\u5e0c\\u8868\\u4e2d\\u6dfb\\u52a0\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n 2. \\u5728\\u54c8\\u5e0c\\u8868\\u4e2d\\u67e5\\u627e\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n 3. \\u4ece\\u54c8\\u5e0c\\u8868\\u4e2d\\u5220\\u9664\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n C# 10<\\/a> \\u8fd0\\u884c\\u5728 .NET 6 \\u4e0a<\\/p>\"],\"javascript\":[\"JavaScript\",\" \\u7248\\u672c\\uff1a \\u60a8\\u7684\\u4ee3\\u7801\\u5728\\u6267\\u884c\\u65f6\\u5c06\\u5e26\\u4e0a lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"],\"ruby\":[\"Ruby\",\" \\u4f7f\\u7528 \\u4e00\\u4e9b\\u5e38\\u7528\\u7684\\u6570\\u636e\\u7ed3\\u6784\\u5df2\\u5728 Algorithms \\u6a21\\u5757\\u4e2d\\u63d0\\u4f9b\\uff1ahttps:\\/\\/www.rubydoc.info\\/github\\/kanwei\\/algorithms\\/Algorithms<\\/p>\"],\"swift\":[\"Swift\",\" \\u7248\\u672c\\uff1a \\u6211\\u4eec\\u901a\\u5e38\\u4fdd\\u8bc1\\u66f4\\u65b0\\u5230 Apple\\u653e\\u51fa\\u7684\\u6700\\u65b0\\u7248Swift<\\/a>\\u3002\\u5982\\u679c\\u60a8\\u53d1\\u73b0Swift\\u4e0d\\u662f\\u6700\\u65b0\\u7248\\u7684\\uff0c\\u8bf7\\u8054\\u7cfb\\u6211\\u4eec\\uff01\\u6211\\u4eec\\u5c06\\u5c3d\\u5feb\\u66f4\\u65b0\\u3002<\\/p>\"],\"golang\":[\"Go\",\" \\u7248\\u672c\\uff1a \\u652f\\u6301 https:\\/\\/godoc.org\\/github.com\\/emirpasic\\/gods@v1.18.1<\\/a> \\u7b2c\\u4e09\\u65b9\\u5e93\\u3002<\\/p>\"],\"python3\":[\"Python3\",\" \\u7248\\u672c\\uff1a \\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982array<\\/a>, bisect<\\/a>, collections<\\/a>\\u3002 \\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u9700\\u4f7f\\u7528 Map\\/TreeMap \\u6570\\u636e\\u7ed3\\u6784\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 sortedcontainers<\\/a> \\u5e93\\u3002<\\/p>\"],\"scala\":[\"Scala\",\" \\u7248\\u672c\\uff1a \\u7248\\u672c\\uff1a \\u6211\\u4eec\\u4f7f\\u7528\\u7684\\u662f JetBrains \\u63d0\\u4f9b\\u7684 experimental compiler\\u3002\\u5982\\u679c\\u60a8\\u8ba4\\u4e3a\\u60a8\\u9047\\u5230\\u4e86\\u7f16\\u8bd1\\u5668\\u76f8\\u5173\\u7684\\u95ee\\u9898\\uff0c\\u8bf7\\u5411\\u6211\\u4eec\\u53cd\\u9988<\\/p>\"],\"rust\":[\"Rust\",\" \\u7248\\u672c\\uff1a \\u652f\\u6301 crates.io \\u7684 rand<\\/a><\\/p>\"],\"php\":[\"PHP\",\" With bcmath module.<\\/p>\"],\"typescript\":[\"TypeScript\",\" TypeScript 5.1.6<\\/p>\\r\\n\\r\\n Compile Options: --alwaysStrict --strictBindCallApply --strictFunctionTypes --target ES2022<\\/p>\\r\\n\\r\\n lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"],\"racket\":[\"Racket\",\"clang 11<\\/code> \\u91c7\\u7528\\u6700\\u65b0C++ 20\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n
-O2<\\/code>\\u7ea7\\u4f18\\u5316\\u3002AddressSanitizer<\\/a> \\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4b
out-of-bounds<\\/code>\\u548c
use-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n
OpenJDK 17<\\/code>\\u3002\\u53ef\\u4ee5\\u4f7f\\u7528Java 8\\u7684\\u7279\\u6027\\u4f8b\\u5982\\uff0clambda expressions \\u548c stream API\\u3002<\\/p>\\r\\n\\r\\n
Python 2.7.12<\\/code><\\/p>\\r\\n\\r\\n
GCC 8.2<\\/code>\\uff0c\\u91c7\\u7528GNU11\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n
-O1<\\/code>\\u7ea7\\u4f18\\u5316\\u3002 AddressSanitizer<\\/a>\\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4b
out-of-bounds<\\/code>\\u548c
use-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n
\\r\\nstruct hash_entry {\\r\\n int id; \\/* we'll use this field as the key *\\/\\r\\n char name[10];\\r\\n UT_hash_handle hh; \\/* makes this structure hashable *\\/\\r\\n};\\r\\n\\r\\nstruct hash_entry *users = NULL;\\r\\n\\r\\nvoid add_user(struct hash_entry *s) {\\r\\n HASH_ADD_INT(users, id, s);\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n
\\r\\nstruct hash_entry *find_user(int user_id) {\\r\\n struct hash_entry *s;\\r\\n HASH_FIND_INT(users, &user_id, s);\\r\\n return s;\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n
\\r\\nvoid delete_user(struct hash_entry *user) {\\r\\n HASH_DEL(users, user); \\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\"],\"csharp\":[\"C#\",\"
Node.js 16.13.2<\\/code><\\/p>\\r\\n\\r\\n
--harmony<\\/code> \\u6807\\u8bb0\\u6765\\u5f00\\u542f \\u65b0\\u7248ES6\\u7279\\u6027<\\/a>\\u3002<\\/p>\\r\\n\\r\\n
Ruby 3.1<\\/code>\\u6267\\u884c<\\/p>\\r\\n\\r\\n
Swift 5.5.2<\\/code><\\/p>\\r\\n\\r\\n
Go 1.21<\\/code><\\/p>\\r\\n\\r\\n
Python 3.10<\\/code><\\/p>\\r\\n\\r\\n
Scala 2.13<\\/code><\\/p>\"],\"kotlin\":[\"Kotlin\",\"
Kotlin 1.9.0<\\/code><\\/p>\\r\\n\\r\\n
rust 1.58.1<\\/code><\\/p>\\r\\n\\r\\n
PHP 8.1<\\/code>.<\\/p>\\r\\n\\r\\n