Redundant Connection II

本文介绍了一种算法,用于从给定的有向图中移除一条边,使其变为一棵合法的有根树。该算法首先检查是否存在节点拥有两个父节点的情况,若存在,则记录这两条边并尝试移除其中之一;若不存在,则寻找包含根节点的环,并移除导致成环的边。

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

Redundant Connection II

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.

FROM:
LeetCode-Algorithms-graph

这道题要我们从给出边中删去一条边,使有向图成为一棵树。
显然有两种情况:
1.有个节点有两个父亲
2.有环
因此我们先遍历一次所有边,看看是否有节点有两个父亲,有的话记录下来,记这两条边为e1,e2,并且把后面出现的那条边e2删除,然后判断剩余边是否是一棵合法树,是则应删除e2,否则应删除e1。
如果没有节点有两个父亲,就意味着有一个包括了根节点的环。一条一条边加入构图,看看是否成环,只需判断加入的边u,v是否有共同祖先。

class Solution {
public:
    vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
        int parent[1001];
        int n, u, v, parent_u;
        vector<int> e1, e2;
        for (int i = 0; i < 1001; i++) {
            parent[i] = -1;
        }
        for (auto edge:edges) {
            if (parent[edge[1]] != -1) {
                e1 = {parent[edge[1]],edge[1]};
                e2 = edge;
            } else {
                parent[edge[1]]= edge[0];
            }
        }
        for (int i = 0; i < 1001; i++) {
            parent[i] = i;
        }
        if (e1.empty()) {
            for (auto edge:edges) {
                u = edge[0];
                v = edge[1];
                parent[u] = getParent(parent, u);
                if (parent[u] != parent[v]) {
                    parent[v] = parent[u];
                } else {
                    return edge;
                }
            }
        } else {
            for (auto edge:edges) {
                if (edge[1] == e2[1] && edge[0] == e2[0]) continue;
                u = edge[0];
                v = edge[1];
                parent[u] = getParent(parent, u);
                if (parent[u] != parent[v]) {
                    parent[v] = parent[u];
                } else {
                    return e1;
                }
            }
        }
        return e2;
    }


    int getParent(int* parent, int i) {
        if (parent[i] == i) {
            return i;
        } else {
            return getParent(parent, parent[i]);
        }
    }
};
### 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)** 此列表并非官方发布版本而是基于社区反馈整理而成。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值