2359. 找到离给定两个节点最近的节点

题目链接

2359. 找到离给定两个节点最近的节点 - 力扣(LeetCode)

题目描述

给你一个 n 个节点的 有向图 ,节点编号为 0n - 1 ,每个节点 至多 有一条出边。

有向图用大小为 n 下标从 0 开始的数组 edges 表示,表示节点 i 有一条有向边指向 edges[i] 。如果节点 i 没有出边,那么 edges[i] == -1

同时给你两个节点 node1node2

请你返回一个从 node1node2 都能到达节点的编号,使节点 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 。

解题思路

  1. 问题描述
    • 给定一个有向图(edges 数组表示,edges[i] 表示节点 i 指向的节点),以及两个起始节点 node1node2
    • 需要找到一个节点 i,使得:
      • node1node2 都能到达 i
      • i 是满足条件的节点中,max(dis1[i], dis2[i]) 最小的节点(即两个节点到 i 的距离的最大值最小)。
      • 如果有多个满足条件的节点,返回编号最小的那个。
  2. 核心思路
    • node1node2 分别出发,计算它们到所有其他节点的最短距离(dis1dis2)。
    • 遍历所有节点,找到同时满足以下条件的节点 i
      • dis1[i]dis2[i] 均不为 n(表示两个节点都能到达 i)。
      • max(dis1[i], dis2[i]) 最小。
    • 如果存在多个满足条件的节点,选择编号最小的那个。
  3. 关键点
    • 使用 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;
    }
}

复杂度分析

  1. 时间复杂度
    • calcDis 方法:
      • 遍历所有节点最多一次(因为一旦访问过就会跳过),时间复杂度为 O(n)。
    • 主方法 closestMeetingNode
      • 调用两次 calcDis,时间复杂度为 O(n)。
      • 遍历所有节点比较距离,时间复杂度为 O(n)。
    • 总时间复杂度:O(n)。
  2. 空间复杂度
    • 需要存储 dis1dis2 两个距离数组,大小为 O(n)。
    • 总空间复杂度:O(n)。
相关推荐
To_OC7 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎8 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC9 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
delishcomcn10 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹10 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
雪碧聊技术10 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划
CV-Climber13 小时前
检索技术的实际应用
人工智能·算法
hhzz13 小时前
Tiger AI Platform平台中增加人脸识别功能
图像处理·人工智能·算法·计算机视觉·大模型
从零开始的代码生活_14 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法