leetcode 685. 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.


根据题意,所给出的输入为一棵树和一条多余的边,并在输入中找到这条多余的边。这棵树除根节点外,都有一个确定的根节点。
那么就会存在一下三种情况

  • 只有环

    环

这种情况下,选择最后一条组成环的边 remove

  • degree > 1
    入度大于2
    这种情况下,首先记录产生入度为2的边,并且记首先出现的边为 first ,后出现的边为 second 。此时,remove second

  • 有环 且 degree > 1
    both of all
    remove 组成环 且 造成deg > 1的边


class Solution {
private:
    int root[1024];
public:
    vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
        for(register int i=0;i<=1000;i++)
            root[i]=0;
        vector<int> first,second;
        int peak=0;
        for(auto& ele: edges){
            peak=max(peak,ele[0]);
            peak=max(peak,ele[1]);
            if(root[ele[1]]==0){
                root[ele[1]]=ele[0];
            }else{
                second=ele;
                first.push_back(root[ele[1]]);
                first.push_back(ele[1]);
                ele[0]=0;
            }
        }
        for(register int i=1;i<=peak;i++)
            root[i]=i;
        for(auto ele : edges){
            if(ele[0]==0)
                continue;
            int rootA=seekRoot(ele[0]);
            int rootB=seekRoot(ele[1]);
            if(rootA==rootB){
                return first.empty()? ele:first;
            }
            root[rootA]=rootB;
        }
        return second;
    }
    int seekRoot(int x){
        if(x==root[x])
            return x;
        else{
            int r=seekRoot(root[x]);
            return root[x]=r;
        }
    }
};

说明:
首先遍历给出的边,寻找是否有 deg > 1 的情况。辅助数组 root ,其中 root[i] 表示节点 i 的父节点,初始值为 0 。如果有 deg > 1 的情况,记录造成这种情况的边。
第二次遍历使用并查集查询是否有环。但遍历的过程不包括 second 。

  • case 1

对应于第一种情况,将会在第一次遍历中记录 且 第二次遍历不返回值。直到函数末尾返回 second 。

  • case 2
    对应于第二种情况,第一次遍历中无记录 且 第二次遍历发现环并返回构成环的边。

  • case 3

对应于第三种情况,采用枚举可能两条边的方法。在第一次遍历中记录 first 和 second 。并且规避了 second 在第二次遍历中被访问。其后进入第二次遍历,如果 first 为组成环 且 造成 deg > 1 的边,则在第二次遍历中将会返回 first ;如果没有在第二次遍历中找到环,则说明产生环 且 deg > 1 的边,是为访问到的 second 。故在遍历结束后返回 second 。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值