Java實現 LeetCode 815 公交路線(創建關係+BFS)

815. 公交路線

我們有一系列公交路線。每一條路線 routes[i] 上都有一輛公交車在上面循環行駛。例如,有一條路線 routes[0] = [1, 5, 7],表示第一輛 (下標爲0) 公交車會一直按照 1->5->7->1->5->7->1->… 的車站路線行駛。

假設我們從 S 車站開始(初始時不在公交車上),要去往 T 站。 期間僅可乘坐公交車,求出最少乘坐的公交車數量。返回 -1 表示不可能到達終點車站。

示例:
輸入:
routes = [[1, 2, 7], [3, 6, 7]]
S = 1
T = 6
輸出: 2
解釋:
最優策略是先乘坐第一輛公交車到達車站 7, 然後換乘第二輛公交車到車站 6。
說明:

1 <= routes.length <= 500.
1 <= routes[i].length <= 500.
0 <= routes[i][j] < 10 ^ 6.

import java.awt.Point;
class Solution {
    public int numBusesToDestination(int[][] routes, int S, int T) {
       if (S == T) {
            return 0;
        }
        int numsOfBus = routes.length;
        List<List<Integer>> busGraph = new ArrayList<>();
        for (int i = 0; i < numsOfBus; i++) {
            Arrays.sort(routes[i]);
            busGraph.add(new ArrayList<>());
        }
        //把有相同站點的車聯繫起來
        for (int i = 0; i < numsOfBus; i++) {
            for (int j = i + 1; j < numsOfBus; j++) {
                if (intersect(routes[i], routes[j])) {
                    busGraph.get(i).add(j);
                    busGraph.get(j).add(i);
                }
            }
        }
        Queue<int[]> queue = new LinkedList<>();
        List<Integer> seen = new ArrayList<>();
        List<Integer> targets = new ArrayList<>();
        // 包含起點的加入起始隊列,包含目的地的加入目標隊列
        // seen用來確保
        for (int i = 0; i < numsOfBus; i++) {
            if (Arrays.binarySearch(routes[i], S) >= 0) {
                seen.add(i);
                queue.add(new int[]{i, 0});
            }
            if (Arrays.binarySearch(routes[i], T) >= 0) {
                targets.add(i);
            }
        }
//BFS走起
        while (!queue.isEmpty()) {
            
                int[] cur = queue.poll();
                int busLine = cur[0];
                int depth = cur[1];
                if (targets.contains(busLine)) {
                    return depth + 1;
                }
                List<Integer> neighbors = busGraph.get(busLine);
                for (int k = 0; k < neighbors.size(); k++) {
                    if (!seen.contains(neighbors.get(k))) {
                        seen.add(neighbors.get(k));
                        queue.add(new int[]{neighbors.get(k), depth + 1});
                    }
                }
            
        }
        return -1;
    }

    private boolean intersect(int[] route1, int[] route2) {
        int len1 = route1.length;
        int len2 = route2.length;
        int i = 0;
        int j = 0;
        while (i < len1 && j < len2) {
            if (route1[i] == route2[j]) {
                return true;
            }
            if (route1[i] > route2[j]) {
                j++;
            }
            else
            {
                i++;
            }
        }
        return false;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章