Java机考题:815. 公交路线 图论BFS

给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。

  • 例如,路线 routes[0] = [1, 5, 7] 表示第 0 辆公交车会一直按序列 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ... 这样的车站路线行驶。

现在从 source 车站出发(初始时不在公交车上),要前往 target 车站。 期间仅可乘坐公交车。

求出 最少乘坐的公交车数量 。如果不可能到达终点车站,返回 -1

示例 1:

复制代码
输入:routes = [[1,2,7],[3,6,7]], source = 1, target = 6
输出:2
解释:最优策略是先乘坐第一辆公交车到达车站 7 , 然后换乘第二辆公交车到车站 6 。 

示例 2:

复制代码
输入:routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
输出:-1

方法思路

  1. 建立车站到公交车的映射

    • 使用 Map<Integer, List<Integer>> stopToBuses 记录每个车站有哪些公交车经过。

    • 例如:车站 1 有公交车 [0, 2] 经过。

  2. BFS 广度优先搜索

    • source 出发,每次尝试乘坐当前车站的所有公交车,并记录到达新车站的最小换乘次数。

    • 优化 :一旦某辆公交车的路线被遍历过,就标记为 null,避免重复处理。

  3. 边界情况处理

    • 如果 source == target,直接返回 0(不用坐车)。

    • 如果 sourcetarget 没有公交车经过,返回 -1


java 复制代码
class Solution {
    public int numBusesToDestination(int[][] routes, int source, int target) {
        // 记录经过车站 x 的公交车编号
        Map<Integer, List<Integer>> stopToBuses = new HashMap<>();
        for (int i = 0; i < routes.length; i++) {
            for (int x : routes[i]) {
                stopToBuses.computeIfAbsent(x, k -> new ArrayList<>()).add(i);
            }
        }

        // 如果没有公交车经过起点或终点,直接返回
        if (!stopToBuses.containsKey(source) || !stopToBuses.containsKey(target)) {
            // 注意原地 TP 的情况
            return source != target ? -1 : 0;
        }

        // BFS
        Map<Integer, Integer> dis = new HashMap<>();
        dis.put(source, 0);
        Queue<Integer> q = new ArrayDeque<>();
        q.add(source);
        while (!q.isEmpty()) {
            int x = q.poll(); // 当前在车站 x
            int disX = dis.get(x);
            for (int i : stopToBuses.get(x)) { // 遍历所有经过车站 x 的公交车 i
                if (routes[i] != null) {
                    for (int y : routes[i]) { // 遍历公交车 i 的路线
                        if (!dis.containsKey(y)) { // 没有访问过车站 y
                            dis.put(y, disX + 1); // 从 x 站上车然后在 y 站下车
                            q.add(y);
                        }
                    }
                    routes[i] = null; // 标记 routes[i] 遍历过
                }
            }
        }

        return dis.getOrDefault(target, -1);
    }
}
相关推荐
天天爱吃肉821820 小时前
豆包 vs DeepSeek API 对比分析报告
android·java·大数据·开发语言·功能测试·嵌入式硬件·汽车
柏舟飞流20 小时前
Spring Boot + Spring Security + RBAC:从登录鉴权到权限模型设计
java·spring boot·spring
AC赳赳老秦20 小时前
OpenClaw + 飞书多维表格:自动同步数据、生成统计图表、触发自动化任务
java·大数据·python·缓存·自动化·deepseek·openclaw
CS_SKILL20 小时前
吉比特 C++ 实习一面面经:一轮把 C++、容器、并发、排序和网络全扫了一遍
java·开发语言·校招面经·实习面经·技术面经·吉比特校招
Jul1en_21 小时前
【SpringCloud】SkyWalking 链路追踪知识详解及部署教程
java·后端·spring·spring cloud·skywalking
宸津-代码粉碎机21 小时前
Spring AI 企业级实战|智能记忆摘要+自动遗忘机制落地,彻底解决上下文爆炸与Token冗余
java·大数据·人工智能·后端·python·spring·云计算
逻极21 小时前
Spring Boot 微服务开发提速:我们如何将接口响应时间降低60%
java·spring boot·微服务·性能优化·自动配置
Yvonne爱编码21 小时前
JAVA EE初阶---DAY 2 计算机网络
java·开发语言·计算机网络·算法·java-ee·php
潇凝子潇21 小时前
IDEA插件
java·ide·intellij-idea
摇滚侠21 小时前
SSM 框架实战教程 SpringBoot 自动配置 176-179
java·spring boot·后端