Design subway system - the importance of selecting a suitable container

0x01. Issues

You implement a class UndergroundSystemthat supports the following three methods:

  1. checkIn(int id, string stationName, int t):
    Number idof passengers at ta time into the subway station stationName.
    A passenger can enter or leave a subway station at the same time.
  2. checkOut(int id, string stationName, int t):
    Number idof passengers at the ttime of leaving the subway station stationName.
  3. getAverageTime(string startStation, string endStation):
    Return from the subway station startStationto subway station endStationaverage time spent.
    The average travel time calculation of all including the current date from the startStation 直接到达 endStationstroke.
    Call getAverageTimetime, ask the route contains at least a trip itinerary.

When you call getAverageTime, ask the route contains at least a trip itinerary.

You may assume that for all checkInand checkOutcalls are logical. That is, if a customer in the t1arrival time of a subway station, then the time of his departure t2must meet t2 > t1. All events are given in chronological order.

输入示例:
[“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 is);
undergroundSystem.checkOut (32, "Cambridge", 22 is);
undergroundSystem.getAverageTime ( "Paradise", "Cambridge" ); // returns 14.0. From "Paradise" (time 8) to "Cambridge" (time 22) travel only a trip
undergroundSystem.getAverageTime ( "Leyton", "Waterloo "); // return 11.0. A total of 2 lying from "Leyton" to "Waterloo" stroke number id = passenger 45 starting at time = 3 arrive at time = 15, number id = passenger 27 in time = 10 starting at time = 20 reach . Therefore, the average time is ((15-3) + (20-10)) / 2 = 11.0
undergroundSystem.checkIn (10, "Leyton", 24);
undergroundSystem.getAverageTime ( "Leyton", "Waterloo"); // Returns 11.0
undergroundSystem.checkOut (10, "Waterloo", 38 is);
undergroundSystem.getAverageTime ( "Leyton", "Waterloo"); // return 12.0

C++类形式:
class UndergroundSystem {
public:
    UndergroundSystem() {
        
    }
    
    void checkIn(int id, string stationName, int t) {
        
    }
    
    void checkOut(int id, string stationName, int t) {
        
    }
    
    double getAverageTime(string startStation, string endStation) {
        
    }
};
调用说明:

 * 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);

Note: This question comes from Leetcode 182 games third week tournament title

0x02. Brief analysis

Carefully read the title, in fact, I found that the problem is not difficult, but it needs to pay attention to the following places:

  • When two stations with an average take into account all the lines of these two stations.
  • There may be multiple stand side by side with the same name, but the standard is to determine the line of the occupant's id.
    Once you have the basic idea, this problem can have a variety of practices, provided the following two ideas:

AC is a thinking game code, the effect is relatively poor
idea think after the game two for the code works well

0x03 ideas violence - indiscriminate use of container

During the game, and sometimes can not think so much, I feel the problem is simple, so wanted a simple idea:

  • In each station to station name, id, time is deposited into the container.
  • Herein refers to the container structure to be nested with the container C I ideas.
  • Finally, calculate the average time to time, double loop, to find a starting point, and then go to the end and then see which is not the same id information, if any, will be calculated, and re-start looking for the next starting point, so traversal All information is stored.

This method is very rough, it can be said is very poor, but when the game turned out to be over, with the 2s.

  • This approach is the wrong place first select the wrong container, causing a lot of unnecessary waste of space, such as station name in the same there is in fact stored in a different place.
  • Secondly, the first two functions but no data stored in the brain, and not to process the data, resulting in a last function requires a large amount of data to traverse, very time-consuming.

Here is the code AC of the game:

class UndergroundSystem {
public:
    struct StationInformation {
        int id;
        int time;
    };
    struct station {
        string name;
        vector<struct StationInformation> p;
    };
    vector<struct station> All;
    UndergroundSystem() {

    }

    void checkIn(int id, string stationName, int t) {
        struct StationInformation informations;
        informations.id = id;
        informations.time = t;
        struct station c;
        c.name = stationName;
        c.p.push_back(informations);
        All.push_back(c);
    }

    void checkOut(int id, string stationName, int t) {
        struct StationInformation informations;
        informations.id = id;
        informations.time = t;
        struct station c;
        c.name = stationName;
        c.p.push_back(informations);
        All.push_back(c);
    }

    double getAverageTime(string startStation, string endStation) {
        vector<struct StationInformation> startSationInformation;
        vector<struct StationInformation> endStationInformation;
        double count = 0;
        double time = 0;
        for (int i = 0; i < All.size() - 1; i++) {
        ss:     if (All[i].name == startStation) {
                    startSationInformation = All[i].p;
                    for (int j = i + 1; j < All.size(); j++) {
                        if (All[j].name == endStation) {
                            endStationInformation = All[j].p;
                            for (int k = 0; k < startSationInformation.size(); k++) {
                                for (int h = 0; h < endStationInformation.size(); h++) {
                                    if (startSationInformation[k].id == endStationInformation[h].id) {
                                        time += endStationInformation[h].time - startSationInformation[k].time;
                                        count++;
                                        i++;
                                        goto ss;
                                    }
                                }
                            }
                        }
                    }
                }
        }
        return time / count;
    }
};

0x04. Jiaoyou ideas and pair with the use -map

After the game think carefully and found that, by mapand pairused together, can. Ideas are as follows:

  • With a the Map tableid, for a certain time on station and car id record.
  • When the car long enough to record.
  • Get off, we use a the Map result, recording start and end points of the combined string, as well as the time spent, the number of lines.
  • Because the topics to ensure the legitimacy of the data, indicating that the passengers must get off before the car, as long as all correspondence must control id on the line.
  • tableidIn the form of:unordered_map<int, pair<string, int>> tableid;
  • resultIn the form of:unordered_map<string, pair<double, int>> result;

Here is the code:

class UndergroundSystem {
private:
    unordered_map<int, pair<string, int>> tableid;
    unordered_map<string, pair<double, int>> result;
public:
    UndergroundSystem() {

    }

    void checkIn(int id, string stationName, int t) {
        tableid[id] = { stationName ,t };
    }

    void checkOut(int id, string stationName, int t) {
        string name = tableid[id].first + stationName;
        t -= tableid[id].second;
        result[name].first += (double)t;
        result[name].second++;
    }

    double getAverageTime(string startStation, string endStation) {
        string name = startStation + endStation;
        return result[name].first / result[name].second;
    }
};

  • Both space consumption is almost, but the gap time is dozens of times.
  • So choose a suitable container to store the data is really important.

ATFWUS --Writing By 2020–03–29

Published 160 original articles · won praise 179 · views 10000 +

Guess you like

Origin blog.csdn.net/ATFWUS/article/details/105177723