leetcode--重新規劃路線

JR_Chan發表於2020-06-04

 題目是LeetCode第191場周賽的第三題,連結:1466. 重新規劃路線。具體描述見原題。

 題目可以用BFS來解決,不過首先我們需要先建立兩個鄰接表toNextreverse分別代表正常的鄰接表和逆的鄰接表(也就是邊的方向反了過了)。然後套用BFS模板,先將0號節點入隊,只要佇列非空就執行以下迴圈:

  • 出隊一個節點node,從toNext中獲得node的鄰接節點,只要未訪問過則入隊(同時這表明有一條路徑需要進行反轉),從reverse獲得指向node的那些節點,只要未訪問過,就入隊(這種路徑不用反轉,已經是符合要求的了)。

 每個節點最多出入隊一次,故時間複雜度為 O ( n ) O(n) O(n),空間複雜度為 O ( n ) O(n) O(n)

 JAVA版程式碼如下:

class Solution {
    public int minReorder(int n, int[][] connections) {
        Map<Integer, List<Integer>> toNext = new HashMap<>();
        Map<Integer, List<Integer>> reverse = new HashMap<>();
        for (int[] c : connections) {
            if (toNext.containsKey(c[0])) {
                toNext.get(c[0]).add(c[1]);
            }
            else {
                List<Integer> item = new LinkedList<>();
                item.add(c[1]);
                toNext.put(c[0], item);
            }
            if (reverse.containsKey(c[1])) {
                reverse.get(c[1]).add(c[0]);
            }
            else {
                List<Integer> item = new LinkedList<>();
                item.add(c[0]);
                reverse.put(c[1], item);
            }
        }
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(0);
        int result = 0;
        boolean[] visited = new boolean[n];
        visited[0] = true;
        while (!queue.isEmpty()) {
            int node = queue.poll();
            if (reverse.containsKey(node)) {
                for (int nextNode : reverse.get(node)) {
                    if (!visited[nextNode]) {
                        visited[nextNode] = true;
                        queue.offer(nextNode);
                    }
                }
            }
            if (toNext.containsKey(node)) {
                for (int nextNode : toNext.get(node)) {
                    if (!visited[nextNode]) {
                        visited[nextNode] = true;
                        queue.offer(nextNode);
                        ++result;
                    }
                }
            }
        }
        return result;
    }
}

 提交結果如下:

leetcode--重新規劃路線

 這裡時間不咋地,因為題目的測試資料比較弱,是有排序關係的,所以看了一下有不少人利用這一點從而沒有建鄰接表,但是這種做法在輸入資料一旦亂序的話答案就錯了,所以這裡先不糾結時間不咋地的問題了。

 Python版程式碼如下:

class Solution:
    def minReorder(self, n: int, connections: List[List[int]]) -> int:
        toNext = collections.defaultdict(list)
        reverse = collections.defaultdict(list)
        visited = [False] * n
        for con in connections:
            toNext[con[0]].append(con[1])
            reverse[con[1]].append(con[0])
        queue = collections.deque()
        queue.append(0)
        visited[0] = True
        result = 0
        while len(queue) > 0:
            node = queue.popleft()
            for nextNode in reverse[node]:
                if not visited[nextNode]:
                    visited[nextNode] = True
                    queue.append(nextNode)
            for nextNode in toNext[node]:
                if not visited[nextNode]:
                    visited[nextNode] = True
                    queue.append(nextNode)
                    result += 1
        return result

 提交結果如下:

leetcode--重新規劃路線

相關文章