1. 程式人生 > >815. 公交路線

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