2359. Find Closest Node to Given Two Nodes

Medium

You are given a directed graph of n nodes numbered from 0 to n - 1, where each node has at most one outgoing edge.

The graph is represented with a given 0-indexed array edges of size n, indicating that there is a directed edge from node i to node edges[i]. If there is no outgoing edge from i, then edges[i] == -1.

You are also given two integers node1 and node2.

Return the index of the node that can be reached from both node1 and node2, such that the maximum between the distance from node1 to that node, and from node2 to that node is minimized. If there are multiple answers, return the node with the smallest index, and if no possible answer exists, return -1.

Note that edges may contain cycles.

Example 1:

Input: edges = [2,2,3,-1], node1 = 0, node2 = 1
Output: 2
Explanation: The distance from node 0 to node 2 is 1, and the distance from node 1 to node 2 is 1.
The maximum of those two distances is 1. It can be proven that we cannot get a node with a smaller maximum distance than 1, so we return node 2.

Example 2:

Input: edges = [1,2,-1], node1 = 0, node2 = 2
Output: 2
Explanation: The distance from node 0 to node 2 is 2, and the distance from node 2 to itself is 0.
The maximum of those two distances is 2. It can be proven that we cannot get a node with a smaller maximum distance than 2, so we return node 2.

Constraints:

  • n == edges.length

  • 2 <= n <= 10^5

  • -1 <= edges[i] < n

  • edges[i] != i

  • 0 <= node1, node2 < n

解題

func closestMeetingNode(edges []int, node1 int, node2 int) int {
    var bfs func(int) []int
    bfs = func(node int) []int {
        stack := []int{ node }
        l := make([]int, len(edges)) // 記錄 node 可以到的地方需要的步數
        l[node] = 0

        visited := make([]bool, len(edges)) // 記錄走過的點,不需要再加入 stack 了
        visited[node] = true

        for len(stack) != 0 {
            cur := stack[0] // 目前走到的點
            stack = stack[1:] // 把目前走到的點從 stack 移除
            nxt := edges[cur] // 下一個可以到的點

            if nxt == -1 || visited[nxt] { // 接下來沒點可以走了,或是下一個點走過了
                break
            } else {
                l[nxt] = l[cur] + 1
                stack = append(stack, nxt)
                visited[nxt] = true
            }
        }

        return l
    }

    l1 := bfs(node1) // 記錄 node1 到每個點需要的步數
    l2 := bfs(node2) // 記錄 node2 到每個點需要的步數

    ans := -1 // 答案
    tmp := math.MaxInt32 // 目前到答案節點需要的步數
    for i:=0; i<len(edges); i++ {
        if l1[i] == 0 && i != node1 { continue } // 非 node1 、到達的步數卻是0,代表這個點 node1 根本到不了
        if l2[i] == 0 && i != node2 { continue } // 非 node2 、到達的步數卻是0,代表這個點 node2 根本到不了

        if max(l1[i], l2[i]) < tmp { // 兩個點都可以到達 i ,且步數比到目前的答案更少
            tmp = max(l1[i], l2[i]) // 更新步數
            ans = i // 更新答案
        }
    }

    return ans
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

Last updated