815. 公交路线

题目

我们有一系列公交路线。每一条路线 routes[i] 上都有一辆公交车在上面循环行驶。例如,有一条路线 routes[0] = [1, 5, 7],表示第一辆 (下标为0) 公交车会一直按照 1->5->7->1->5->7->1->… 的车站路线行驶。

假设我们从 S 车站开始(初始时不在公交车上),要去往 T 站。 期间仅可乘坐公交车,求出最少乘坐的公交车数量。返回 -1 表示不可能到达终点车站。

示例:
输入:
routes = [[1, 2, 7], [3, 6, 7]]
S = 1
T = 6
输出: 2
解释:
最优策略是先乘坐第一辆公交车到达车站 7, 然后换乘第二辆公交车到车站 6。
说明:

1 <= routes.length <= 500.
1 <= routes[i].length <= 500.
0 <= routes[i][j] < 10 ^ 6.

思路

这一题的主要思路就是广搜,那么我们可以考虑在每个公交站上标记经过它的线路,这样先遍历新增的点,再遍历这些点的线路(之前没走过的),不断循环即可。
这一次开始只跑了160ms,看到个76ms的算法和我的思路是一样的,然后发现unordered_map效率比map要高不少。同时也要注意判断冗余不一定都会加快速度,例如这一次若公交线路经过一些之前已经经过了的点,那么要判断这些点是否已经访问过的代价是挺大的(只能用map,因为公交站的站号很大),其实这些点就算冗余也没什么关系,因为一个点不可能有太多公交线路经过,用一个bool数组确保这些线路也不会重新访问,还是可以接受的。

class Solution {
public:
    int numBusesToDestination(vector<vector<int>>& routes, int startPoint, int aimPoint){
        if(startPoint == aimPoint){
            return 0;
        }
        unordered_map<int ,vector<int> > pointMp; //map的查找比unordered_map慢。
        queue<int> nextPoint ;
        nextPoint.push(startPoint);
        vector<bool> visitRoute(routes.size() , false);
        int nowPointLength , nowDepth = 0;
        for(int loop = 0 ;loop < routes.size() ; loop++ ){
            for(int loop1 = 0 ; loop1 < routes[loop].size() ; loop1++){
                int nowPoint = routes[loop][loop1];
                pointMp[nowPoint ].push_back(loop);
            }
        }
        while(!nextPoint.empty()){
            vector<int> nextRoute;
            nowPointLength = nextPoint.size();// 新一层的长度,因为nextPoint的大小会在后面改变,这里先记录
            nowDepth++;
            while(nowPointLength --){ // 遍历新的一层的公交站
                int nowPoint = nextPoint.front();
                nextPoint.pop();
                for(auto nowRoute:pointMp[nowPoint]){ // 遍历公交站的线路
                    if(!visitRoute[ nowRoute ] ){
                        visitRoute[ nowRoute ] = true;
                        for(auto nowPoint:routes[nowRoute]){ // 将线路上没有访问过的点加入nextPoint
                            nextPoint.push(nowPoint); //用一个map检测点是否访问过,访问过就不放进nextPoint速度更慢
                                                    //应该是因为map的访问是logN复杂度,但一般情况下一个点只有少量线路
                                                    //重新遍历也没关系
                            if(nowPoint == aimPoint){
                                return nowDepth;
                            }
                        }
                    }
                }
            }
        }
        return -1;
    }
};

猜你喜欢

转载自blog.csdn.net/DDghsot/article/details/82947882