题目链接
2359. 找到离给定两个节点最近的节点 - 力扣(LeetCode)
题目描述
给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,每个节点 至多 有一条出边。
有向图用大小为 n 下标从 0 开始的数组 edges 表示,表示节点 i 有一条有向边指向 edges[i] 。如果节点 i 没有出边,那么 edges[i] == -1 。
同时给你两个节点 node1 和 node2 。
请你返回一个从 node1 和 node2 都能到达节点的编号,使节点 node1 和节点 node2 到这个节点的距离 较大值最小化。如果有多个答案,请返回 最小 的节点编号。如果答案不存在,返回 -1 。
注意 edges 可能包含环。
题目示例
示例 1 :

plain
输入:edges = [2,2,3,-1], node1 = 0, node2 = 1
输出:2
解释:从节点 0 到节点 2 的距离为 1 ,从节点 1 到节点 2 的距离为 1 。
两个距离的较大值为 1 。我们无法得到一个比 1 更小的较大值,所以我们返回节点 2 。
示例 2 :

plain
输入:edges = [1,2,-1], node1 = 0, node2 = 2
输出:2
解释:节点 0 到节点 2 的距离为 2 ,节点 2 到它自己的距离为 0 。
两个距离的较大值为 2 。我们无法得到一个比 2 更小的较大值,所以我们返回节点 2 。
解题思路
- 问题描述 :
- 给定一个有向图(
edges数组表示,edges[i]表示节点i指向的节点),以及两个起始节点node1和node2。 - 需要找到一个节点
i,使得:node1和node2都能到达i。i是满足条件的节点中,max(dis1[i], dis2[i])最小的节点(即两个节点到i的距离的最大值最小)。- 如果有多个满足条件的节点,返回编号最小的那个。
- 给定一个有向图(
- 核心思路 :
- 从
node1和node2分别出发,计算它们到所有其他节点的最短距离(dis1和dis2)。 - 遍历所有节点,找到同时满足以下条件的节点
i:dis1[i]和dis2[i]均不为n(表示两个节点都能到达i)。max(dis1[i], dis2[i])最小。
- 如果存在多个满足条件的节点,选择编号最小的那个。
- 从
- 关键点 :
- 使用
calcDis方法计算从某个节点出发的最短距离,利用贪心遍历(类似 BFS 的思想)。 - 初始化距离为
n(表示无法到达),遍历时更新可达节点的距离。 - 最终比较所有节点的
max(dis1[i], dis2[i]),选择最小值。
- 使用
题解代码
java
class Solution {
// 主方法:找到两个节点都能到达的最近交汇节点
public int closestMeetingNode(int[] edges, int node1, int node2) {
// 计算从 node1 出发到所有节点的最短距离
int[] dis1 = calcDis(edges, node1);
// 计算从 node2 出发到所有节点的最短距离
int[] dis2 = calcDis(edges, node2);
int n = edges.length;
int minDis = n; // 初始最小距离设为最大值(n 表示无法到达)
int ans = -1; // 初始答案为 -1(表示无解)
// 遍历所有节点,寻找满足条件的交汇节点
for (int i = 0; i < n; i++) {
// 当前节点的最大距离(即两个节点到该节点的距离的较大值)
int d = Math.max(dis1[i], dis2[i]);
// 如果当前节点的最大距离更小,则更新答案
if (d < minDis) {
minDis = d;
ans = i;
}
}
return ans;
}
// 辅助方法:计算从节点 x 出发到所有其他节点的最短距离
private int[] calcDis(int[] edges, int x) {
int n = edges.length;
int[] dis = new int[n];
Arrays.fill(dis, n); // 初始化所有距离为 n(表示无法到达或尚未访问)
// 从 x 出发,沿着边遍历,直到无路可走(x=-1)或重复访问节点(dis[x]<n)
for (int d = 0; x >= 0 && dis[x] == n; x = edges[x]) {
dis[x] = d++; // 记录当前节点的距离,并递增距离
}
return dis;
}
}
复杂度分析
- 时间复杂度 :
calcDis方法:- 遍历所有节点最多一次(因为一旦访问过就会跳过),时间复杂度为 O(n)。
- 主方法
closestMeetingNode:- 调用两次
calcDis,时间复杂度为 O(n)。 - 遍历所有节点比较距离,时间复杂度为 O(n)。
- 调用两次
- 总时间复杂度:O(n)。
- 空间复杂度 :
- 需要存储
dis1和dis2两个距离数组,大小为 O(n)。 - 总空间复杂度:O(n)。
- 需要存储