Leetcode 815. Bus Routes

Problem:

We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->... forever.

We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what is the least number of buses we must take to reach our destination? Return -1 if it is not possible.

Example:
Input: 
routes = [[1, 2, 7], [3, 6, 7]]
S = 1
T = 6
Output: 2
Explanation: 
The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.

Note:

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

  这道题看到最少数量的公交车就应该有使用BFS的预感,先来说说我最开始考虑的解法,首先用一个哈希表记录每一个站点stop经过的所有线路的公交车,公交车编号为routes的索引。然后用visited记录访问过的公交车编号。BFS肯定是要维护一个队列的,里面的元素pair第一个元素代表第first路公交,第二个元素代表该公交经过第second站。首先将所有包含S站的公交全部放入队列,表示只需要一量公交可以到达的所有站点,然后在循环中记录下队列长度,然后将所有未访问过的公交车可能到达的所有站点加入队列中,同时pop开始元素,直到找到T为止,理论上说这个解法的时间复杂度是没问题的,可能是由于测试用例的缘故时间稍慢。

 1 class Solution {
 2 public:
 3     int numBusesToDestination(vector<vector<int>>& routes, int S, int T) {
 4         if(S == T) return 0;
 5         unordered_map<int,vector<int>> um;
 6         for(int i = 0;i != routes.size();++i){
 7             for(int j = 0;j != routes[i].size();++j){
 8                 um[routes[i][j]].push_back(i);
 9             }
10         }
11         vector<int> visited(routes.size(),false);
12         queue<pair<int,int>> q;
13         for(int i = 0;i != um[S].size();++i){
14             int busline = um[S][i];
15             for(int j = 0;j != routes[busline].size();++j){
16                 q.push(make_pair(busline,routes[busline][j]));
17                 if(routes[busline][j] == T)
18                     return 1;
19             }
20             visited[busline] = true;
21         }
22         int result = 2;
23         while(!q.empty()){
24             int m = q.size();
25             for(int i = 0;i != m;++i){
26                 int busline = q.front().first;
27                 int stop = q.front().second;
28                 q.pop();
29                 for(int k = 0;k != um[stop].size();++k){
30                     if(visited[um[stop][k]]) continue;
31                     for(int t = 0;t != routes[um[stop][k]].size();++t){
32                         q.push(make_pair(um[stop][k],routes[um[stop][k]][t]));
33                         if(routes[um[stop][k]][t] == T) return result;
34                     }
35                     visited[um[stop][k]] = true;
36                 }
37             }
38             result++;
39         }
40         return -1;
41     }
42 };

  接下来讲另一种解法,大致思路类似,不同的是这回pair中第一个元素记录站点,第二个元素记录坐过的公交车数量,visited记录做过的站点,然后在队列中不断添加该公交车可以换乘到达的站点。注意为什么push的一定是可以换乘到达的站点,这是由于同一条线路上的其他站点必然已经添加过队列了(细细体会这个细节)。

Code:

 1 class Solution {
 2 public:
 3     int numBusesToDestination(vector<vector<int>>& routes, int S, int T) {
 4         if(S == T) return 0;
 5         unordered_map<int,vector<int>> um;
 6         for(int i = 0;i != routes.size();++i){
 7             for(int j = 0;j != routes[i].size();++j){
 8                 um[routes[i][j]].push_back(i);
 9             }
10         }
11         unordered_set<int> visited;
12         visited.insert(S);
13         queue<pair<int,int>> q;
14         q.push(make_pair(S,0));
15         while(!q.empty()){
16             int stop = q.front().first;
17             int transfer = q.front().second;
18             q.pop();
19             for(int i = 0;i != um[stop].size();++i){
20                 for(int j = 0;j != routes[um[stop][i]].size();++j){
21                     if(T == routes[um[stop][i]][j]) return transfer+1;
22                     if(visited.find(routes[um[stop][i]][j]) == visited.end()){
23                         visited.insert(routes[um[stop][i]][j]);
24                         q.push(make_pair(routes[um[stop][i]][j],transfer+1));
25                     }
26                 }
27                 routes[um[stop][i]].clear();
28             }
29         }
30         return -1;
31     }
32 };

猜你喜欢

转载自www.cnblogs.com/haoweizh/p/10238335.html
今日推荐