leetcode-6134:找到离给定两个节点最近的节点

简介: leetcode-6134:找到离给定两个节点最近的节点

题目

题目连接

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

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

同时给你两个节点 node1 和 node2 。

请你返回一个从 node1 和 node2 都能到达节点的编号,使节点 node1 和节点 node2 到这个节点的距离 较大值最小化。如果有多个答案,请返回 最小 的节点编号。如果答案不存在,返回 -1 。

注意 edges 可能包含环。

示例 1:

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

示例 2:

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

解题

方法一:哈希

创建1个哈希集合,记录从node1开始经过的节点,那么从node2开始遍历,第一次经过set中已经有的节点,那么就是交点。

但是此时不能保证就是最小距离,因此还要类似相同重复一遍,从node2开始的节点记录到set,然后从node1开始第一次遇到set中已有的节点。

取两个路径结果中的最小值,就是最终的节点。

创建2个数组,visit数组记录节点是否访问过,len数组记录当前节点到起始节点的距离

从node1开始,遍历到结束(-1的点或者已经访问过的点),同时更新visit和len数组

class Solution {
public:
    int closestMeetingNode(vector<int>& edges, int node1, int node2) {
        pair<int,int> p1=fun(edges,node1,node2);
        pair<int,int> p2=fun(edges,node2,node1);
        if(p1.first==p2.first) return p1.first;//如果是同一个节点,那么直接返回节点
        else{
            if(p1.second==p2.second) return min(p1.first,p2.first);//如果节点不同,但是距离相同,选编号小的节点
            else if(p1.second<p2.second) return p1.first;//如果节点不同,且距离不同,那么选距离小的节点
            else return p2.first;
        }
    }
    pair<int,int> fun(vector<int>& edges, int node1, int node2){//返回值:(节点,路径)
        unordered_set<int> set;//记录node1开始,经过的节点
        vector<bool> visit(edges.size(),false);//visit数组记录节点是否访问过(作用:防止出现环,死循环)
        int i=node1;
        vector<int> len(edges.size(),-1);//len数组记录经过的节点的距离node1的距离
        int curLen=0;
        while(true){
            if(i==-1||visit[i]==true) break;//如果节点没有出边 或者 节点访问过,那么直接break
            visit[i]=true;
            len[i]=curLen++;
            set.insert(i);
            i=edges[i];//访问下一个节点
        }
        visit=vector<bool>(edges.size(),false);
        i=node2;
        curLen=0;
        while(true){
            if(i==-1||visit[i]==true) return {-1,-1};
            visit[i]=true;
            if(set.count(i)){//如果该节点从node1开始访问过,说明这是一个交点
                int resLen=max(len[i],curLen);//取最大的路径
                return {i,resLen};
            }
            curLen++;
            i=edges[i];
        }
        return {-1,-1};
    }
};
相关文章
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
17 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
40 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
15 0
|
3月前
|
算法
LeetCode第24题两两交换链表中的节点
这篇文章介绍了LeetCode第24题"两两交换链表中的节点"的解题方法,通过使用虚拟节点和前驱节点技巧,实现了链表中相邻节点的交换。
LeetCode第24题两两交换链表中的节点
|
3月前
|
Python
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
39 4
【Leetcode刷题Python】450. 删除二叉搜索树中的节点
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
54 5
|
3月前
|
Python
【Leetcode刷题Python】222. 完全二叉树的节点个数
LeetCode第222题"完全二叉树的节点个数"的Python代码实现,通过递归和深度优先遍历的方法来计算给定完全二叉树的节点总数。
40 5
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
41 4
|
5月前
|
算法 数据可视化 数据挖掘
哈希表+DFS快速解决力扣129题:求根节点到叶节点数字之和
哈希表+DFS快速解决力扣129题:求根节点到叶节点数字之和
|
6月前
|
存储
【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点
【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点
47 1