• 815. Bus Routes


    问题:

    给定多条bus线路,routes[i]代表 bus i 的所有经停站点。

    给定source起始站,和target目标站,求最少换乘几辆车能到达目的地。

    Example 1:
    Input: routes = [[1,2,7],[3,6,7]], source = 1, target = 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.
    
    Example 2:
    Input: routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
    Output: -1
     
    Constraints:
    1 <= routes.length <= 500.
    1 <= routes[i].length <= 105
    All the values of routes[i] are unique.
    sum(routes[i].length) <= 105
    0 <= routes[i][j] < 106
    0 <= source, target < 106
    

      

    解法:BFS

    分析:本问题中,

    • 经过的站点,不再经过,
    • 坐过的线路,也不再乘坐。

    因此可使用两个visited数组,来标记已经乘坐过的线路or经过的站点。

    通过给定的线路信息,构造站点上的所有bus结构体

    • unordered_map<int,vector<int>> stop_buses;//dest, bus_no
    • stop_buses[i]代表 站点 i 上可换乘的所有bus。

    将当前所在的站点,入队。

    • queue.push(source);
    • 同时标记该站点访问过,visited.insert(source)

    遍历队列,

    • 每一层为换乘一次。res++
    • 对于当前站点cur_stop:
      • 若==target,那么已经以最少换乘次数到达目标地点。返回res。
      • 否则在当前站点,开始尝试所有未尝试过的bus。
    • bus_i : stop_buses[cur_stop]
      • 对这些bus_i中,的任意一站 stop_i : bus_i
      • (未停过的站点:visited[stop_i]不存在)
      • 加入尝试下车站点。queue.push(stop_i)
    • 尝试过该bus_i中的所有站点后,将这条线路清空,(以后其他尝试方法,不再尝试这条线路,本次尝试已经尝试过该条线路,以最少换乘)

    代码参考:

     1 class Solution {
     2 public:
     3     int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
     4         unordered_map<int,vector<int>> stop_buses;//dest, bus_no
     5         for(int i=0; i<routes.size(); i++) {//bus[i]
     6             for(auto stp:routes[i]) {//every stop in this bus
     7                 stop_buses[stp].push_back(i);
     8             }
     9         }
    10         int res = 0;
    11         unordered_set<int> visited_stop;
    12         queue<int> q;//stop
    13         q.push(source);
    14         visited_stop.insert(source);
    15         while(!q.empty()) {
    16             int sz = q.size();
    17             for(int i=0; i<sz; i++) {
    18                 int cur_stop = q.front();
    19                 q.pop();
    20                 if(cur_stop == target) return res;
    21                 for(int b:stop_buses[cur_stop]) {//choose bus
    22                     for(int stop:routes[b]) {//every stop in this bus route
    23                         if(visited_stop.insert(stop).second) {
    24                             q.push(stop);
    25                         }
    26                     }
    27                     routes[b].clear();
    28                     //one bus only to take once.
    29                 }
    30             }
    31             res++;
    32         }
    33         return -1;
    34     }
    35 };
  • 相关阅读:
    数据库表的主外键
    数据库条件查询及关系搭建
    MySQL数据库的基本认识与操作
    MySQL5.7安装详解及常见安装问题解决
    数据库介绍
    Sensor图像调试
    1.线性表
    发展建议
    typedef 与 #define 的区别
    音频处理
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14494099.html
Copyright © 2020-2023  润新知