|  | 
|  | 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