[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;
    }
}
posted @ 2021-06-28 23:47  ACBingo  阅读(102)  评论(0编辑  收藏  举报