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)。
相关推荐
江畔柳前堤20 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore21 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考1 天前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX1 天前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面1 天前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号1 天前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽1 天前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI1 天前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者1 天前
征程6工具链模型X86推理方式说明
算法
地平线开发者1 天前
【征程6】校准量化中HistogramObserver解析
算法