Medium草稿★★★★★O(n) 時間 · O(n) 空間
GraphBFSDFS
Patterns🌊 廣度優先 BFS🕸️ 圖遍歷・連通分量
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

2359Find Closest Node to Given Two NodesGraphsMediumGraphs

給定一個有向圖,每個節點最多有一條出邊,用 edges[i] 表示(-1 表示無出邊)。給定兩個節點 node1node2,找一個節點使得 max(dist(node1, node), dist(node2, node)) 最小。若有多個答案,回傳編號最小的。

Example:

Input: edges = [2,2,3,-1], node1 = 0, node2 = 1 Output: 2

Intuition

TIP

分別從 node1 和 node2 出發計算到所有可達節點的距離,找兩者都能到達且最大距離最小的節點。

Approaches

⭐ 1. Two Distance Passes — O(n) / O(n)
  • Idea: 從 node1 和 node2 分別遍歷計算距離,然後遍歷所有節點找最佳答案
  • Time: O(n)
  • Space: O(n)
class Solution {
    fun closestMeetingNode(edges: IntArray, node1: Int, node2: Int): Int {
        val n = edges.size
        val dist1 = getDist(edges, node1, n)
        val dist2 = getDist(edges, node2, n)

        var minDist = Int.MAX_VALUE
        var result = -1

        for (i in 0 until n) {
            if (dist1[i] != -1 && dist2[i] != -1) {
                val maxD = maxOf(dist1[i], dist2[i])
                if (maxD < minDist) {
                    minDist = maxD
                    result = i
                }
            }
        }
        return result
    }

    private fun getDist(edges: IntArray, start: Int, n: Int): IntArray {
        val dist = IntArray(n) { -1 }
        var cur = start
        var d = 0
        while (cur != -1 && dist[cur] == -1) {
            dist[cur] = d
            d++
            cur = edges[cur]
        }
        return dist
    }
}
2. Same Logic, BFS Form — O(n) / O(n)
  • Idea: 用 BFS 風格遍歷計算距離
  • Time: O(n)
  • Space: O(n)
class Solution {
    fun closestMeetingNode(edges: IntArray, node1: Int, node2: Int): Int {
        val n = edges.size

        fun bfs(start: Int): IntArray {
            val dist = IntArray(n) { -1 }
            val queue = ArrayDeque<Int>()
            queue.add(start)
            dist[start] = 0
            while (queue.isNotEmpty()) {
                val cur = queue.removeFirst()
                val next = edges[cur]
                if (next != -1 && dist[next] == -1) {
                    dist[next] = dist[cur] + 1
                    queue.add(next)
                }
            }
            return dist
        }

        val dist1 = bfs(node1)
        val dist2 = bfs(node2)

        var minDist = Int.MAX_VALUE
        var result = -1
        for (i in 0 until n) {
            if (dist1[i] != -1 && dist2[i] != -1) {
                val maxD = maxOf(dist1[i], dist2[i])
                if (maxD < minDist) {
                    minDist = maxD
                    result = i
                }
            }
        }
        return result
    }
}

🔑 Takeaways