815. Bus Routes

本文探讨了一种算法,用于解决从起点S到终点T,通过最少次数的公交换乘到达目的地的问题。采用广度优先搜索(BFS)策略,通过维护一个从公交站到可换乘公交线路的地图,确保每次迭代都能找到距离起点最近的公交站。
Description

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.

Problem URL


Solution

给一个二维数组,ith数组表示了i号公交途径的bus stops。问从S到T需要坐几路公交车。

For each of the bus stop, we maintain all the buses (bus routes) that go through it. To do that, we use a HashMap, where bus stop number is the key and all the buses (bus routes) that go through it are added to an ArrayList.

We use BFS, where we process elements in a level-wise manner. We add the Start bus stop in the queue. Next, when we enter the while loop, we add all the bus stops that are reachable by all the bus routes that go via the Start. Thus, if we have the input as [[1, 2, 7], [3, 6, 7]] and Start as 6, then upon processing bus stop 6, we would add bus stops 3 and 7.
With this approach, all the bus stops at a given level, are “equal distance” from the start node, in terms of number of buses that need to be changed.

To avoid loops, we also maintain a HashSet that stores the buses that we have already visited.

Note that while in this approach, we use each stop for doing BFS, one could also consider each bus (route) also for BFS.

Code
class Solution {
    public int numBusesToDestination(int[][] routes, int S, int T) {
        //a map contains map from bus stop number to the bus routes could be switched to.
        Map<Integer, ArrayList<Integer>> map = new HashMap<>();
        //a queue contains current stops we could reach.
        Queue<Integer> queue = new LinkedList<>();
        HashSet<Integer> visited = new HashSet<>();
        int res = 0;
        
        if (S == T){
            return res;
        }
        
        for (int i = 0; i < routes.length; i++){
            for (int j = 0; j < routes[i].length; j++){
                ArrayList<Integer> buses = map.getOrDefault(routes[i][j], new ArrayList<>());
                buses.add(i);
                map.put(routes[i][j], buses);
            }
        }
        
        queue.offer(S);
        while (!queue.isEmpty()){
            int size = queue.size();
            res++;
            for (int i = 0; i < size; i++){
                int current = queue.poll();
                ArrayList<Integer> buses = map.get(current);
                for (int bus : buses){
                    if (visited.contains(bus)){
                        continue;
                    }
                    visited.add(bus);
                    for (int j = 0; j < routes[bus].length; j++){
                        if (routes[bus][j] == T){
                            return res;
                        }
                        queue.offer(routes[bus][j]);
                    }
                }
            }
        }
        return -1;
    }
}

Time Complexity: O(N^2)
Space Complexity: O(N^2 + sumbi)


Review
### LeetCode 815. Bus Routes 的解决方案 此问题的核心在于如何高效地计算从起始站点 `S` 到目标站点 `T` 所需的最少公交车辆数目。可以通过构建一个基于 **广度优先搜索(BFS)** 的算法来解决该问题。 #### 思路解析 为了实现 BFS,可以将每个公交路线视为图中的一个节点。两个节点之间存在边当且仅当它们共享至少一个相同的停靠站。这样做的目的是减少不必要的重复访问,并优化时间复杂度。具体来说: - 构建一张映射表 `to_routes`,其中键为某个特定的公交站点编号,而值是一个列表,表示哪些公交线路覆盖了这个站点[^2]。 - 初始化队列 `q` 并设置初始状态 `(S, 0)` 表示当前位于起点 `S` 处,尚未搭乘任何公交车。 - 创建两个布尔数组分别用于标记已经访问过的站点 (`visited`) 和已经处理过的公交线路 (`route_visited`) 来防止冗余操作。 在每一次迭代过程中: - 取出队首元素并判断其是否为目标站点;如果是,则立即返回所需的换乘次数; - 对于当前站点所关联的所有未被探索的公交线路逐一分析这些线路上其他可能抵达的新站点,并将其加入待处理队列中同时更新相应的标志位。 以下是完整的 C++ 实现代码: ```cpp class Solution { public: int numBusesToDestination(vector<vector<int>>& routes, int S, int T) { if(S == T){ return 0; } // Build mapping from stop -> list of routes that pass through this stop. unordered_map<int, vector<int>> to_routes; for(int i = 0; i < routes.size(); ++i){ for(auto &stop : routes[i]){ to_routes[stop].emplace_back(i); } } queue<pair<int, int>> q; // Queue stores pairs of current stop and number of buses taken so far. unordered_set<int> seen_stops;// Set keeps track of visited stops. vector<bool> seen_routes(routes.size(), false); // Array tracks which bus routes have been used. q.emplace(S, 0); seen_stops.insert(S); while(!q.empty()){ auto [current_stop, buses_taken] = q.front(); q.pop(); // Explore all possible next steps via available bus routes at 'current_stop'. for(auto &r : to_routes[current_stop]){ if(seen_routes[r]) continue; seen_routes[r] = true; for(auto &next_stop : routes[r]){ if(next_stop == T){ return buses_taken + 1; } if(seen_stops.find(next_stop)==seen_stops.end()){ seen_stops.insert(next_stop); q.emplace(next_stop, buses_taken + 1); } } } } return -1; // If no path found after exhausting search space. } }; ``` 以上程序实现了题目要求的功能,并利用了高效的 BFS 方法来寻找最短路径。 #### 关键点说明 - 如果起始位置等于终点位置则无需乘车直接返回零次交换即满足条件[^3]。 - 建立哈希表存储各站点对应的可选交通方式以便快速检索相邻关系。 - 应用双层循环结构逐级扩展候选集合直至发现匹配项或者穷尽全部可能性为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值