[LeetCode] 815. 公交路线

Posted ACBingo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] 815. 公交路线相关的知识,希望对你有一定的参考价值。

朴素BFS,擦边过。。不难,但是绕,需要想清楚。
大致描述一下做法吧,首先枚举能经过起点站的公交车,将公交车入队列。
然后对当前公交车能到达的每一站,看能否换乘其它公交车,将其它公交车入队。
注意,已经“坐过”的公交车就没有意义再坐一次了,当然,已经去过的站也没有必要再去一次了。所以有两个visitedSet

class Solution {
    public int numBusesToDestination(int[][] routes, int source, int target) {
        if (source == target) return 0;
        Map<Integer, List<Integer>> station = new HashMap<>();

        int n = routes.length;
        for (int i=0;i<n;i++) {
            for (int j=0;j<routes[i].length;j++){
                if (!station.containsKey(routes[i][j])) {
                    station.put(routes[i][j], new ArrayList<>());
                }
                station.get(routes[i][j]).add(i);
            }
        }

        if (!station.containsKey(target)) return -1;

        Set<Integer> set = new HashSet<>();
        set.add(source);

        Queue<Integer> q = new ArrayDeque<>();
        Queue<Set<Integer>> visitedQ = new ArrayDeque<>();
        Queue<Set<Integer>> visitedBus = new ArrayDeque<>();
        Queue<Integer> cntQ = new ArrayDeque<>();

        q.add(source);
        visitedQ.add(set);
        cntQ.add(1);

        Set<Integer> setBus = new HashSet<>();
        visitedBus.add(setBus);

        while (!q.isEmpty()) {
            Integer curStation = q.poll();
            Set<Integer> visited = visitedQ.poll();
            int cnt = cntQ.poll();
            Set<Integer> vBus = visitedBus.poll();

            List<Integer> bus = station.get(curStation);
            if (bus!=null) {
                for (Integer curBus : bus) {
                    if (vBus.contains(curBus)) continue;
                    int[] route = routes[curBus];
                    for (int nextStation : route) {
                        if (!visited.contains(nextStation)) {
                            if (nextStation == target) {
                                return cnt;
                            } else {
                                q.add(nextStation);
                                Set<Integer> newVis = new HashSet<>(visited);
                                newVis.add(nextStation);
                                visitedQ.add(newVis);
                                cntQ.add(cnt + 1);

                                Set<Integer> newVBus = new HashSet<>(vBus);
                                newVBus.add(curBus);
                                visitedBus.add(newVBus);
                            }
                        }
                    }
                }
            }
        }

        return -1;
    }
}

以上是关于[LeetCode] 815. 公交路线的主要内容,如果未能解决你的问题,请参考以下文章

[Hbfs] lc815. 公交路线(建图+多源bfs+bfs最短路+思维+好题)

LeetCode 815 公交线路[BFS Map] HERODING的LeetCode之路

[LeetCode] 815. Bus Routes 巴士路线

LeetCode 1184. 公交站间的距离

LeetCode1184. 公交站间的距离(C++)

安卓百度地图怎么没有公交路线查询