[LeetCode Daily Question] 685. Redundant Connection II

[LeetCode Daily Question] 685. Redundant Connection II

685. Redundant Connection II

Question source link
algorithm idea: tree, depth-first traversal, directed graph, and search;

Enter a directed graph consisting of a tree with N nodes (the node values ​​do not repeat 1, 2, …, N) and an additional edge. The two vertices of the additional edge are contained between 1 and N. This additional edge does not belong to an existing edge in the tree
Insert picture description here

Topic analysis

Analysis source link
definition:
Conflict edge: the edge that causes a node to have two parent nodes, such as [[2,1],[3,1]], [3,1] are saved as conflict edges.
Ring edge: the edge that causes the ring to be generated, such as [[1,2],[2,3],[3,1]], [3,1] are saved as ring edge.
Analysis of all situations:
1. No conflict and ring: no conflict, then directly return to the ring edge
Example: [[1,2], [2,3], [3,4], [4,1], [1 ,5]], at this time [4,1] will produce a ring, but no conflict.
Insert picture description here
2. Acyclic, conflict: If acyclic, it will directly return to the conflict side, ie [u,v]
Example: [[1,2], [1,3], [2,3]], at this time [2, 3] There will be conflicts, but no loops.
Insert picture description here
3. There are conflicts and rings: In this case, the conflicting edges should be retained, because the influence of the ring is more prior to the conflict, so remove the edge that will cause the conflict in the ring, ie [parent[v],v]
example: [[2,1],[3,1],[1,4],[4,2]], at this time [3,1] produces a conflict, [4,2] produces a ring, and the conflict side should be retained [3 ,1], by finding the parent node of 1, thereby obtaining the conflicting edge in the ring: [2,1]
Insert picture description here

Data structure-union search set

Brief description: A data structure to quickly obtain whether the two exist in the same set. False merges the two sets. In this question, True represents a ring.

java code

Code source link

class Solution {
    
    
    public int[] findRedundantDirectedConnection(int[][] edges) {
    
    
        //辅助数组parent以及并查集初始化
        int nodesCount = edges.length;//边的数量=结点的数量
        UnionFind uf = new UnionFind(nodesCount + 1);
        int[] parent = new int[nodesCount + 1];//存放每个结点的父亲结点
        for (int i = 1; i <= nodesCount; ++i) {
    
    
            parent[i] = i;//初始化,每个结点的父亲结点是自己
        }
        //冲突/环标签
        int conflict = -1;//冲突:该结点入度为2
        int cycle = -1;//环:成环
		//开始遍历
        //[[1,2], [1,3], [2,3]]
        for (int i = 0; i < nodesCount; ++i) {
    
    
            int[] edge = edges[i];//获取其中一条边<node1,node2>;
            int node1 = edge[0], node2 = edge[1];
            if (parent[node2] != node2) {
    
    
                conflict = i;
            } else {
    
    
                parent[node2] = node1;//改变父亲结点
                if (uf.find(node1) == uf.find(node2)) {
    
    //判断是否成环
                    cycle = i; 
                } else {
    
    
                    uf.union(node1, node2);//合并结点1和结点2
                }
            }
        }
        //获取有问题的边(冲突,环)
        if (conflict < 0) {
    
    //没有冲突,那意味着有成环;
            int[] redundant = {
    
    edges[cycle][0], edges[cycle][1]};
            return redundant;
        } else {
    
    
            int[] conflictEdge = edges[conflict];//冲突边<node1,node2>;
            if (cycle >= 0) {
    
    
                int[] redundant = {
    
    parent[conflictEdge[1]], conflictEdge[1]};
                return redundant;
            } else {
    
    
                int[] redundant = {
    
    conflictEdge[0], conflictEdge[1]};
                return redundant;
            }
        }
    }
}
//并查集:快速获取两者是否存在于同一集合;即判断是否有环
class UnionFind {
    
    //用来存放边
    int[] ancestor;
	//初始化,每个结点指向的边是自己
    public UnionFind(int n) {
    
    
        ancestor = new int[n];
        for (int i = 0; i < n; i++) {
    
    
            ancestor[i] = i;
        }
    }
	//将index1的集合加入到index2的集合中
    public void union(int index1, int index2) {
    
    
        ancestor[find(index1)] = find(index2);
    }
	//用来查找index的祖先
    public int find(int index) {
    
    
        if (ancestor[index] != index) {
    
    
            ancestor[index] = find(ancestor[index]);
        }
        return ancestor[index];
    }
}

Guess you like

Origin blog.csdn.net/qq_39457586/article/details/108639822