Design Underground System - Problem

Imagine you're tasked with building the tracking system for a massive underground railway network like the London Underground or NYC Subway. Your system needs to track millions of passenger journeys and provide real-time analytics about travel times between stations.

You'll implement an UndergroundSystem class that handles three core operations:

  • Check-In: When a passenger taps their card at a station entrance
  • Check-Out: When a passenger taps their card at their destination
  • Analytics: Calculate average travel times between any two stations

The system must efficiently track passenger movements and compute travel statistics from historical data. Think of it as building the brain behind those "Average journey time: 23 minutes" displays you see in subway stations!

Key Requirements:

  • Passengers can only be checked into one location at a time
  • Travel times are directional (A→B may differ from B→A)
  • Average calculations use all historical journeys between two stations
  • The system must handle real-time queries efficiently

Input & Output

example_1.py — Basic Operations
$ Input: undergroundSystem = 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) print(undergroundSystem.getAverageTime("Paradise", "Cambridge")) # 14.00000 print(undergroundSystem.getAverageTime("Leyton", "Waterloo")) # 11.00000 undergroundSystem.checkIn(10, "Leyton", 24) print(undergroundSystem.getAverageTime("Leyton", "Waterloo")) # 11.00000 undergroundSystem.checkOut(10, "Waterloo", 38) print(undergroundSystem.getAverageTime("Leyton", "Waterloo")) # 12.00000
Output: 14.00000 11.00000 11.00000 12.00000
💡 Note: The system tracks multiple passengers simultaneously. Passenger 45 travels Leyton→Waterloo in 12 minutes, passenger 27 takes the same route in 10 minutes, giving an initial average of 11.0. When passenger 10 completes the journey in 14 minutes, the new average becomes (12+10+14)/3 = 12.0 minutes.
example_2.py — Directional Routes
$ Input: undergroundSystem = UndergroundSystem() undergroundSystem.checkIn(1, "A", 0) undergroundSystem.checkOut(1, "B", 10) # A→B: 10 min undergroundSystem.checkIn(2, "B", 5) undergroundSystem.checkOut(2, "A", 20) # B→A: 15 min print(undergroundSystem.getAverageTime("A", "B")) # 10.0 print(undergroundSystem.getAverageTime("B", "A")) # 15.0
Output: 10.0 15.0
💡 Note: Routes are directional - A→B and B→A are tracked separately. This reflects real-world scenarios where travel times can vary based on direction due to factors like traffic patterns, elevation changes, or track configurations.
example_3.py — Multiple Same Routes
$ Input: undergroundSystem = UndergroundSystem() undergroundSystem.checkIn(1, "Station1", 10) undergroundSystem.checkIn(2, "Station1", 20) undergroundSystem.checkIn(3, "Station1", 30) undergroundSystem.checkOut(1, "Station2", 35) # 25 min undergroundSystem.checkOut(2, "Station2", 50) # 30 min undergroundSystem.checkOut(3, "Station2", 45) # 15 min print(undergroundSystem.getAverageTime("Station1", "Station2")) # 23.33333
Output: 23.33333
💡 Note: Multiple passengers taking the same route contribute to the running average: (25+30+15)/3 = 23.33 minutes. The system efficiently maintains this statistic without storing individual trip details.

Visualization

Tap to expand
🚇 Underground System Control Center🎫 Active Passengers MonitorPassenger 123: Paddington → 14:30:15Passenger 456: Kings Cross → 14:45:22Passenger 789: Victoria → 15:02:08⚡ O(1) Check-in/Check-out Operations📊 Route Analytics DatabasePaddington→Westminster: 1,247 trips, 18,705 min totalKings Cross→Angel: 892 trips, 12,688 min totalVictoria→Pimlico: 2,103 trips, 25,236 min total⚡ O(1) Average Time Calculations🧠 Smart Algorithm Benefits• Real-time performance: All operations in O(1) constant time• Minimal memory: Only stores active passengers + route summaries• Scalable: Handles millions of passengers efficiently🔑 Key InsightInstead of storing individual trip records, maintain running totalsAverage = Total Time ÷ Trip Count (computed instantly!)Update Stats
Understanding the Visualization
1
Passenger Check-In
Store passenger ID with their starting station and time in the active passengers table
2
Passenger Check-Out
Calculate journey time, update route statistics, and remove from active passengers
3
Analytics Query
Instantly return average by dividing total time by trip count from route statistics
Key Takeaway
🎯 Key Insight: Use aggregated statistics instead of individual records to achieve O(1) performance for real-time analytics

Time & Space Complexity

Time Complexity
⏱️
O(1)

All operations (checkIn, checkOut, getAverageTime) run in constant time using hash table lookups and updates

n
2n
Linear Growth
Space Complexity
O(P + R)

P is number of active passengers, R is number of unique routes. Much more efficient than storing all individual trips

n
2n
Linear Space

Constraints

  • 1 ≤ id, t ≤ 106
  • 1 ≤ stationName.length, startStation.length, endStation.length ≤ 10
  • All strings consist of uppercase and lowercase English letters and digits
  • At most 2 × 104 calls in total will be made to checkIn, checkOut, and getAverageTime
  • Answers within 10-5 of the actual answer will be accepted
Asked in
Amazon 45 Google 38 Meta 32 Microsoft 28 Uber 25
89.5K Views
High Frequency
~15 min Avg. Time
2.8K Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen