|
| 1 | +package com.fishercoder.solutions; |
| 2 | + |
| 3 | +import java.util.HashMap; |
| 4 | +import java.util.LinkedList; |
| 5 | +import java.util.Map; |
| 6 | + |
| 7 | +/** |
| 8 | + * 1396. Design Underground System |
| 9 | + * |
| 10 | + * Implement the class UndergroundSystem that supports three methods: |
| 11 | + * |
| 12 | + * 1. checkIn(int id, string stationName, int t) |
| 13 | + * A customer with id card equal to id, gets in the station stationName at time t. |
| 14 | + * A customer can only be checked into one place at a time. |
| 15 | + * 2. checkOut(int id, string stationName, int t) |
| 16 | + * A customer with id card equal to id, gets out from the station stationName at time t. |
| 17 | + * 3. getAverageTime(string startStation, string endStation) |
| 18 | + * Returns the average time to travel between the startStation and the endStation. |
| 19 | + * The average time is computed from all the previous traveling from startStation to endStation that happened directly. |
| 20 | + * Call to getAverageTime is always valid. |
| 21 | + * You can assume all calls to checkIn and checkOut methods are consistent. That is, if a customer gets in at time t1 at some station, then it gets out at time t2 with t2 > t1. All events happen in chronological order. |
| 22 | + * |
| 23 | + * Example 1: |
| 24 | + * Input |
| 25 | + * ["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","checkOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","getAverageTime"] |
| 26 | + * [[],[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"]] |
| 27 | + * Output |
| 28 | + * [null,null,null,null,null,null,null,14.0,11.0,null,11.0,null,12.0] |
| 29 | + * |
| 30 | + * Explanation |
| 31 | + * UndergroundSystem undergroundSystem = new UndergroundSystem(); |
| 32 | + * undergroundSystem.checkIn(45, "Leyton", 3); |
| 33 | + * undergroundSystem.checkIn(32, "Paradise", 8); |
| 34 | + * undergroundSystem.checkIn(27, "Leyton", 10); |
| 35 | + * undergroundSystem.checkOut(45, "Waterloo", 15); |
| 36 | + * undergroundSystem.checkOut(27, "Waterloo", 20); |
| 37 | + * undergroundSystem.checkOut(32, "Cambridge", 22); |
| 38 | + * undergroundSystem.getAverageTime("Paradise", "Cambridge"); // return 14.0. There was only one travel from "Paradise" (at time 8) to "Cambridge" (at time 22) |
| 39 | + * undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.0. There were two travels from "Leyton" to "Waterloo", a customer with id=45 from time=3 to time=15 and a customer with id=27 from time=10 to time=20. So the average time is ( (15-3) + (20-10) ) / 2 = 11.0 |
| 40 | + * undergroundSystem.checkIn(10, "Leyton", 24); |
| 41 | + * undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 11.0 |
| 42 | + * undergroundSystem.checkOut(10, "Waterloo", 38); |
| 43 | + * undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return 12.0 |
| 44 | + * |
| 45 | + * Constraints: |
| 46 | + * There will be at most 20000 operations. |
| 47 | + * 1 <= id, t <= 10^6 |
| 48 | + * All strings consist of uppercase, lowercase English letters and digits. |
| 49 | + * 1 <= stationName.length <= 10 |
| 50 | + * Answers within 10^-5 of the actual value will be accepted as correct. |
| 51 | + * */ |
| 52 | +public class _1396 { |
| 53 | + public static class Solution1 { |
| 54 | + public class UndergroundSystem { |
| 55 | + |
| 56 | + class StationAndTime { |
| 57 | + String stationName; |
| 58 | + int t; |
| 59 | + |
| 60 | + public StationAndTime(String stationName, int t) { |
| 61 | + this.stationName = stationName; |
| 62 | + this.t = t; |
| 63 | + } |
| 64 | + |
| 65 | + public String getStation() { |
| 66 | + return this.stationName; |
| 67 | + } |
| 68 | + |
| 69 | + public int getTime() { |
| 70 | + return this.t; |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + Map<String, double[]> averageTimeMap; |
| 75 | + Map<Integer, LinkedList<StationAndTime>> travelerMap = new HashMap<>(); |
| 76 | + |
| 77 | + public UndergroundSystem() { |
| 78 | + averageTimeMap = new HashMap<>(); |
| 79 | + travelerMap = new HashMap<>(); |
| 80 | + } |
| 81 | + |
| 82 | + public void checkIn(int id, String stationName, int t) { |
| 83 | + if (!travelerMap.containsKey(id)) { |
| 84 | + travelerMap.put(id, new LinkedList<>()); |
| 85 | + } |
| 86 | + travelerMap.get(id).add(new StationAndTime(stationName, t)); |
| 87 | + } |
| 88 | + |
| 89 | + public void checkOut(int id, String stationName, int t) { |
| 90 | + LinkedList<StationAndTime> list = travelerMap.get(id); |
| 91 | + StationAndTime stationAndTime = list.getLast(); |
| 92 | + String startToEndStation = stationAndTime.getStation() + "->" + stationName; |
| 93 | + int duration = t - stationAndTime.getTime(); |
| 94 | + if (!averageTimeMap.containsKey(startToEndStation)) { |
| 95 | + averageTimeMap.put(startToEndStation, new double[]{duration, 1}); |
| 96 | + } else { |
| 97 | + double[] pair = averageTimeMap.get(startToEndStation); |
| 98 | + double newAverage = (double) (pair[0] * pair[1] + duration) / (double) (pair[1] + 1); |
| 99 | + averageTimeMap.put(startToEndStation, new double[]{newAverage, pair[1] + 1}); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + public double getAverageTime(String startStation, String endStation) { |
| 104 | + return averageTimeMap.get(startStation + "->" + endStation)[0]; |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | +} |
0 commit comments