首页 > 其他分享 >Leetcode : 684. 冗余连接

Leetcode : 684. 冗余连接

时间:2024-10-28 13:15:54浏览次数:7  
标签:std find edges 节点 查找 数组 684 Leetcode 冗余

> Problem: 684. 冗余连接

题解:冗余连接 (Redundant Connection)

题目描述

给定一棵包含 n 个节点的树(节点值为 1 到 n),向树中添加一条边后形成一个图。你的任务是找出一条可以删除的边,使得删除后剩余部分仍然是一棵有 n 个节点的树。如果有多个答案,返回在输入数组 edges 中最后出现的那个边。

示例

示例 1

输入: edges = [[1,2],[1,3],[2,3]]
输出: [2,3]

示例 2

输入: edges = [[1,2],[1,3],[1,4],[2,4]]
输出: [2,4]

解题思路

本题可以通过并查集(Union-Find)算法有效地解决。并查集能够快速地管理和查询节点的连通性,适合用于检测图中的环。

步骤
  1. 初始化并查集:

    • 创建一个数组 p,用于记录每个节点的父节点,初始时每个节点的父节点是自己。
    • 使用 std::iota 来初始化数组,使得 p[i] = i
  2. 查找函数:

    • 定义一个查找函数 find,通过递归方式找到节点的根节点,并进行路径压缩,以提高后续操作的效率。
  3. 遍历边:

    • 遍历所有边,使用查找函数检查两个节点的根节点。
    • 如果两个节点的根节点相同,说明这条边形成了环,返回这条边。
    • 如果不同,将两个节点合并到同一个集合中。
  4. 返回结果:

    • 最后返回的边即为可以删除的冗余连接。

代码实现

以下是使用 C++ 实现的完整代码:

#include <vector>
#include <numeric>
#include <functional>

class Solution {
public:
    std::vector<int> findRedundantConnection(std::vector<std::vector<int>>& edges) {
        int n = edges.size(); // 获取边的数量
        std::vector<int> p(n); // 初始化父节点数组
        std::iota(p.begin(), p.end(), 0); // 填充父节点数组,p[i] = i

        // 查找函数,使用递归和路径压缩
        std::function<int(int)> find = [&](int x) {
            return x == p[x] ? x : p[x] = find(p[x]); // 路径压缩
        };

        // 遍历边
        for (int i = 0;; ++i) {
            int pa = find(edges[i][0] - 1); // 查找第一个节点的根节点
            int pb = find(edges[i][1] - 1); // 查找第二个节点的根节点
            if (pa == pb) {
                return edges[i]; // 如果两个节点的根节点相同,说明形成了环,返回这条边
            }
            p[pa] = pb; // 合并两个节点的集合
        }
    }
};

代码解析

  1. 初始化父节点数组:

    • 使用 std::iota 填充父节点数组,确保每个节点的父节点最初是自己。
  2. 查找函数:

    • 采用路径压缩的方式查找节点的根,减少查找时间。
  3. 遍历边并合并:

    • 遍历每条边,检查节点是否在同一个集合中。
    • 如果在同一集合,则返回该边,因为它导致了环的形成。

时间复杂度

  • 时间复杂度为 O(n),其中 n 是边的数量。每条边只处理一次,查找和合并操作的效率通过路径压缩得以提升。

空间复杂度

  • 空间复杂度为 O(n),用于存储父节点数组。

总结

通过并查集的方式,我们能够高效地检测图中冗余连接的边。这个解法不仅清晰而且具有良好的性能,适合处理较大的图结构问题。

标签:std,find,edges,节点,查找,数组,684,Leetcode,冗余
From: https://blog.csdn.net/PQ781826/article/details/143268785

相关文章

  • 代码随想录算法训练营第十一天|leetcode150. 逆波兰表达式求值、leetcode239. 滑动窗
    1leetcode150.逆波兰表达式求值题目链接:150.逆波兰表达式求值-力扣(LeetCode)文章链接:代码随想录视频链接:栈的最后表演!|LeetCode:150.逆波兰表达式求值_哔哩哔哩_bilibili自己的思路:这是一道有思路,但是思路并不多的题目,就是我会觉得是先将数据进行添加,然后对于符号通过倒......
  • 【从零开始的LeetCode-算法】713. 乘积小于 K 的子数组
    给你一个整数数组nums和一个整数k,请你返回子数组内所有元素的乘积严格小于k的连续子数组的数目。示例1:输入:nums=[10,5,2,6],k=100输出:8解释:8个乘积小于100的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。需要注意的是[10,5,2]并不......
  • 【从零开始的LeetCode-算法】649. Dota2 参议院
    Dota2的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)Dota2参议院由来自两派的参议员组成。现在参议院希望对一个Dota2游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的一项:禁止一名参议员的权利:参议员可以让另一位......
  • 冗余电路设计
    在电子设计领域,冗余电路是一种广泛应用的技术。它通过引入额外的元件或路径,确保在主电路出现故障时,系统仍能正常运行。冗余电路在航空、医疗和工业自动化等关键领域尤为重要,因为在这些应用中,系统的持续运行直接关系到安全与效率。一、冗余电路的概念冗余电路是指在正常电......
  • leetCode-深度优先遍历
    岛屿数量深度优先遍历classSolution{publicintnumIslands(char[][]grid){intxlen=grid[0].length;intylen=grid.length;intcount=0;for(intx=0;x<xlen;x++){for(inty=0;y<ylen;y++){......
  • leetCode-双指针
     移动零classSolution{publicvoidmoveZeroes(int[]nums){intn=nums.length;intslow=0;intfast=0;while(fast<n){if(nums[fast]!=0){nums[slow++]=nums[fast++];......
  • 算法题——冗余连接
    684.冗余连接题干树可以看成是一个连通且无环的无向图。给定往一棵n个节点(节点值1~n)的树中添加一条边后的图。添加的边的两个顶点包含在1到n中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为n的二维数组edges,edges[i]=[ai,bi]表示图中在a......
  • leetcode每日一题:3181.执行操作可获得的最大总奖励 II
     题干:读本文前,请先弄懂上一篇中的内容,因为这是对上一篇内容的优化:3180.执行操作可获得的最大总奖励I明白上篇的,访问值的影响、复制、上下行之间的关系和算法后可继续看:上一篇中,我们用二维数组,第二维表示了状态空间。但是,在今日的题目中,提交不行,因为占用的空间太太太......
  • LeetCode 3181. 执行操作可获得的最大总奖励 II
    1classSolution{2public:3intmaxTotalReward(vector<int>&rewardValues){4intm=ranges::max(rewardValues);5unordered_set<int>s;6for(intv:rewardValues){7if(s.contains(v))......
  • leetcode-1934-确认率
    链接:1934.确认率-力扣(LeetCode)前提条件:Signups+----------------+----------+|ColumnName|Type|+----------------+----------+|user_id|int||time_stamp|datetime|+----------------+----------+User_id是该表的主键。每一行......