[LeetCode]685. Redundant Connection II

本文介绍了一种算法,用于从一个包含额外边的有向图中找出并移除导致图不再是根树的冗余边。通过分析三种不同情况,即仅有环、节点有多于一个父节点及同时存在的环和多父节点的情况,文章详细解释了如何识别并移除多余的边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • descrption
    In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents.
    The given input is a directed graph that started as a rooted tree with N nodes (with distinct values 1, 2, …, N), with one additional directed edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
    The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] that represents a directed edge connecting nodes u and v, where u is a parent of child v.
    Return an edge that can be removed so that the resulting graph is a rooted tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array.
    Example 1:
Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given directed graph will be like this:
  1
 / \
v   v
2-->3

Example 2:

Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]
Output: [4,1]
Explanation: The given directed graph will be like this:
5 <- 1 -> 2
     ^    |
     |    v
     4 <- 3

Note:
The size of the input 2D-array will be between 3 and 1000.
Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.
- 解题思路
这道题与上一篇文章的题目类似,但是难度有所提升,因为这道题解决的是有向图的问题。所以就不能简单的根据一条边的两个节点有共同的根节点而确定要删除的边是这条。
现在存在三种情况:
(1)有向图中只有环。这种情况就简单将两个节点具有共同根节点的边删去就好。
(2)有向图中没有环,但有个节点有两个父节点。这种情况就将第二次出现不同父节点的边删去就好。
(3)有向图中既有环,而且有个节点还有两个父节点。这时就检测当除去第二次出现父节点的边后,剩余边是不是合法的,如果不合法证明应该删掉的是另一个父节点的边。

  • 代码如下
class Solution {
public:
    vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
        //root of every node, if the root is the same, then the edge is redundant
        int size = edges.size()+1;
        vector<int> parent(size);
        //ans
        vector<int> ans;
        //in the begining, every node's root is itself
        for(int i = 1; i <= edges.size(); i++){
            parent[i] = i;
        }
        vector<int> e1, e2;
        //find out if there is a node has two parent
        for(auto e : edges){
            if(parent[e[1]] != e[1]) { //have another parent
                e1 = {parent[e[1]], e[1]};
                e2 = e;
            }
            else {
                parent[e[1]] = e[0];
            }
        }
        for(int i = 1; i <= edges.size(); i++){
            parent[i] = i;
        }
        if(e1.empty()){
            for(auto e : edges) {
                int u = e[0];
                int v = e[1];
                parent[u] = findparent(parent, u);
                if (parent[u] != parent[v]){
                    parent[v] = parent[u];
                }
                else {
                    return e;
                }
            }
        }
        else {
            for (auto e:edges) {
                if(e[0] == e2[0] && e[1] == e2[1])
                    continue;
                int u = e[0];
                int v = e[1];
                parent[u] = findparent(parent, u);
                if(parent[u] != parent[v]){
                    parent[v] = parent[u];
                }
                else
                    return e1;
            }
        }
        return e2;
    }
    int findparent(vector<int>& parent, int u){
        if(parent[u] == u)
            return u;
        else
            return findparent(parent, parent[u]);
    }
};

原题地址

如有错误请指出,谢谢!

### LeetCode Hot 100 Problems 列表 LeetCode 的热门题目列表通常由社区投票选出,涵盖了各种难度级别的经典编程挑战。这些题目对于准备技术面试非常有帮助。以下是部分 LeetCode 热门 100 题目列表: #### 数组与字符串 1. **两数之和 (Two Sum)** 2. **三数之和 (3Sum)** 3. **无重复字符的最长子串 (Longest Substring Without Repeating Characters)** 4. **寻找两个正序数组的中位数 (Median of Two Sorted Arrays)** #### 动态规划 5. **爬楼梯 (Climbing Stairs)** 6. **不同的二叉搜索树 (Unique Binary Search Trees)** 7. **最大子序列和 (Maximum Subarray)** #### 字符串处理 8. **有效的括号 (Valid Parentheses)** 9. **最小覆盖子串 (Minimum Window Substring)** 10. **字母异位词分组 (Group Anagrams)** #### 图论 11. **岛屿数量 (Number of Islands)** 12. **课程表 II (Course Schedule II)** #### 排序与查找 13. **最接近原点的 K 个点 (K Closest Points to Origin)** 14. **接雨水 (Trapping Rain Water)** 15. **最长连续序列 (Longest Consecutive Sequence)[^2]** #### 堆栈与队列 16. **每日温度 (Daily Temperatures)** 17. **滑动窗口最大值 (Sliding Window Maximum)** #### 树结构 18. **验证二叉搜索树 (Validate Binary Search Tree)** 19. **二叉树的最大路径和 (Binary Tree Maximum Path Sum)** 20. **从前序与中序遍历序列构造二叉树 (Construct Binary Tree from Preorder and Inorder Traversal)** #### 并查集 21. **冗余连接 II (Redundant Connection II)** #### 贪心算法 22. **跳跃游戏 (Jump Game)** 23. **分割等和子集 (Partition Equal Subset Sum)** #### 双指针技巧 24. **环形链表 II (Linked List Cycle II)[^1]** 25. **相交链表 (Intersection of Two Linked Lists)** #### 其他重要题目 26. **LRU缓存机制 (LRU Cache)** 27. **打家劫舍系列 (House Robber I & II)** 28. **编辑距离 (Edit Distance)** 29. **单词拆分 (Word Break)** 此列表并非官方发布版本而是基于社区反馈整理而成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值