LeetCode 685. Redundant Connection II

3 invalid situations

case1: 2 parents no circle

case2: 2 parents with circle

case3: 1 parent with circle

LeetCode 685. Redundant Connection II

 

2 main steps

1 check whether there exists a node with 2 parents, if yes, store the two edges.

2 if no edge yielded from step 1, apply union-find and find the edge creating cycle (same as 684);

   ELSE, apply union-find to ALL edges EXCEPT edges from step 1, then check: if edge 1 from step 1 creates a cycle, return edge 1; else return edge 2.

 

class Solution {
public:
    vector<int> parent;
    vector<int> rank;
    
    vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
        int n=edges.size();
        vector<int> tree_parent(n+1,-1);
        vector<int> edge1{-1,-1}, edge2{-1,-1}; // parent1->child, parent2->child
        
        for (auto edge:edges){
            int n1=edge[0], n2=edge[1];
            if (tree_parent[n2]!=-1){
                edge1 = {tree_parent[n2],n2};
                edge2 = edge;
            }
            tree_parent[n2] = n1;
        }
        
        vector<int> res;
        parent.resize(n+1,-1);
        rank.resize(n+1,0);
        
        if (edge1[0]==-1){ // no node with two parents
            // union find by rank
            for (auto edge:edges){
                int n1=edge[0], n2=edge[1];
                if (Find(n1)!=Find(n2)) 
                    Union(n1,n2);
                else res = edge;
            }
        }else{
            // union find all edges except edge1 and edge2
            for (auto edge:edges){
                if (edge==edge1 || edge==edge2) continue;
                int n1=edge[0], n2=edge[1];
                if (Find(n1)!=Find(n2)) 
                    Union(n1,n2);
                else res = edge;
            }
            
            // if add edge1 cause a loop return edge1
            if (Find(edge1[0])==Find(edge1[1])) res=edge1;
            else res=edge2;
        }
        
        return res;
    }
    
    void Union(int x, int y){
        int rootx=Find(x), rooty=Find(y);
        if (rootx==rooty) return;
        if (rank[rootx]>rank[rooty]){
            parent[rooty] = rootx;
        }else if (rank[rootx]<rank[rooty]){
            parent[rootx] = rooty;
        }else{
            rank[rootx] += 1;
            parent[rooty] = rootx;
        }
    }
        
    int Find(int x){
        if (parent[x]<0) return x;
        return parent[x]=Find(parent[x]);
    }
};

时间复杂度:O(mα(n)) for m operations,amortized O(1) each operation