【每日一题】LeetCode 815.公交路线(广度优先搜索、数组、哈希表)

【每日一题】LeetCode 815.公交路线(广度优先搜索、数组、哈希表)

题目描述

给定一个表示公交线路的数组 routes,其中每个 routes[i] 表示第 i 辆公交车的循环行驶路线。现在从 source 车站出发,要前往 target 车站,期间只能乘坐公交车。要求找出最少乘坐的公交车数量。如果无法到达目标车站,则返回 -1

思路分析

这个问题可以通过图的广度优先搜索(BFS)来解决。我们可以将每个车站看作图中的一个节点,每辆公交车可以看作连接这些节点的边。具体步骤如下:

  1. 建立车站到公交车的映射:首先,我们需要建立一个映射,将每个车站映射到经过该车站的所有公交车。

  2. 判断起点和终点是否可达 :如果起点或终点没有公交车经过,那么无法到达,直接返回 -1

  3. 初始化队列和访问数组:使用一个队列来存储待访问的车站,以及一个数组来记录哪些公交车已经被访问过。

  4. 广度优先搜索:从起点开始,对每个经过起点的公交车进行搜索,找到所有可以到达的车站,并将这些车站加入队列。同时记录每个车站的最少乘坐公交车数量。

  5. 更新距离:对于队列中的每个车站,检查它是否是目标车站,如果是,则返回当前的乘坐公交车数量。如果不是,将其相邻的车站(即同一辆公交车上的其他车站)加入队列,并更新它们的乘坐公交车数量。

  6. 返回结果 :如果队列被清空还没有找到目标车站,说明无法到达,返回 -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

代码实现

java 复制代码
import java.util.*;

class Solution {
    public int numBusesToDestination(int[][] routes, int source, int target) {
        int n = routes.length; // 公交车数量
        if (source == target) return 0; // 如果起点和终点相同,不需要乘坐公交车

        // 建立车站到公交车的映射
        HashMap<Integer, List<Integer>> hm = new HashMap<>();
        for (int i = 0; i < n; i++) {
            for (int x : routes[i]) {
                hm.computeIfAbsent(x, k -> new ArrayList<>()).add(i);
            }
        }

        // 如果起点或终点没有公交车经过,无法到达
        if (!hm.containsKey(source) || !hm.containsKey(target)) return -1;

        // 初始化队列,用于广度优先搜索
        Queue<Integer> que = new ArrayDeque<>();
        boolean[] vis = new boolean[n]; // 记录公交车是否被访问过
        HashMap<Integer, Integer> dis = new HashMap<>(); // 记录每个车站的最少乘坐公交车数量
        dis.put(source, 0); // 起点的乘坐公交车数量为0
        que.offer(source);

        // 广度优先搜索
        while (!que.isEmpty()) {
            int x = que.poll();
            int disX = dis.get(x);
            for (int i : hm.get(x)) {
                if (!vis[i]) {
                    vis[i] = true; // 标记公交车为已访问
                    for (int y : routes[i]) {
                        // 如果这个车站没有被访问过,加入队列并更新距离
                        if (!dis.containsKey(y)) {
                            dis.put(y, disX + 1);
                            que.offer(y);
                        }
                    }
                }
            }
        }

        // 返回目标车站的最少乘坐公交车数量,如果无法到达则返回-1
        return dis.getOrDefault(target, -1);
    }
}
相关推荐
Dream it possible!3 小时前
LeetCode 热题 100_只出现一次的数字(96_136_简单_C++)(哈希表;哈希集合;排序+遍历;位运算)
c++·leetcode·位运算·哈希表·哈希集合
?abc!4 小时前
缓存(5):常见 缓存数据淘汰算法/缓存清空策略
java·算法·缓存
BioRunYiXue4 小时前
一文了解氨基酸的分类、代谢和应用
人工智能·深度学习·算法·机器学习·分类·数据挖掘·代谢组学
jiunian_cn5 小时前
【c++】异常详解
java·开发语言·数据结构·c++·算法·visual studio
工藤新一¹6 小时前
蓝桥杯算法题 -蛇形矩阵(方向向量)
c++·算法·矩阵·蓝桥杯·方向向量
Levin__NLP_CV_AIGC6 小时前
解决pip安装PyPI默认源速度慢
算法·pip
康康这名还挺多6 小时前
鸿蒙HarmonyOS list优化一: list 结合 lazyforeach用法
数据结构·list·harmonyos·lazyforeach
Helibo446 小时前
GESPC++六级复习
java·数据结构·算法
EnticE1527 小时前
[高阶数据结构]二叉树经典面试题
数据结构·算法·面试
MarkHard1237 小时前
Leetcode (力扣)做题记录 hot100(34,215,912,121)
算法·leetcode·职场和发展