[Tree] B016_ verify binary tree (disjoint-set | bfs / dfs)

One, Title Description

二叉树上有 n 个节点,按从 0 到 n - 1 编号,其中节点 i 的两个子节点分别是 leftChild[i] 和 rightChild[i]。

只有 所有 节点能够形成且 只 形成 一颗 有效的二叉树时,返回 true;否则返回 false。

如果节点 i 没有左子节点,那么 leftChild[i] 就等于 -1。右子节点也符合该规则。

注意:节点没有值,本问题中仅仅使用节点编号。

Second, the problem solution

Method a: disjoint-set

Binary nature:

  • The root node is 0
  • Other nodes of the constant is 1.

According to the above properties, we can write the following code, * but it is one-sided answer. 0 is not necessarily the root node.

public boolean validateBinaryTreeNodes(int n, int[] leftChild, int[] rightChild) {
  int[] inDegree = new int[n];
  for (int i = 0; i < n; i++) {
    if (leftChild[i] >= 0)
        inDegree[leftChild[i]]++;
     if (rightChild[i] >= 0)
        inDegree[rightChild[i]]++;
  }

  if (inDegree[0] != 0)
      return false;
  
  for (int i = 1; i < n; i++)
    if (inDegree[i] != 1)
      return false;
  return true;
}

* We code logic read as follows: the degree of the node should be a 0, the node is greater than 1 does not exist.

public boolean validateBinaryTreeNodes(int n, int[] leftChild, int[] rightChild) {
  int[] inDegree = new int[n];
  for (int i = 0; i < n; i++) {
    if (leftChild[i] != -1)
        inDegree[leftChild[i]]++;
     if (rightChild[i] != -1)
        inDegree[rightChild[i]]++;
  }
  int in0 = 0;
  int inOther = 0;
  for (int i : inDegree) {
      if (i == 0) in0++;
      if (i >= 2) inOther++;
  }
  return in0 == 1 && inOther == 0;
}

Here is a point overlooked: * if the tree satisfies the presence of a ring of the degree of a node 0 only, and the absence of nodes is greater than 1.

Therefore, the degree of implementation of simple statistics node does not make sense, we need to judge ring. So here only with disjoint-set to do.

The core logic is twofold:

  • Two nodes are not communicating, where the father of the child node can own at first.
  • Any two nodes is disconnected, i.e., the ring is not present.
public boolean validateBinaryTreeNodes(int n, int[] leftChild, int[] rightChild) {
  UF uf = new UF(n);
  for (int i = 0; i < n; i++) {
    if (leftChild[i] != -1) {
      if (uf.find(leftChild[i]) != leftChild[i] || uf.isConn(leftChild[i], i))
          return false;
      uf.union(i, leftChild[i]);
    }
    if (rightChild[i] != -1) {
      if (uf.find(rightChild[i]) != rightChild[i] || uf.isConn(rightChild[i], i))
          return false;
      uf.union(i, rightChild[i]);
    }
  }
  return uf.count == 1;
}
class UF {
	int[] parent;
	int[] size;
    int count;
    public UF(int N) {
	    count = N;
	    parent = new int[N];
	    size = new int[N];
	    for(int i = 0; i < N; i++) {
		    parent[i] = i;
		    size[i] = 1;
	    }
	}
    public boolean isConn(int p, int q) {
        return find(p) == find(q);
    }
	public int find(int p) {
	    while (p != parent[p]) {
	        p = parent[p];
	    }
	    return p;
	}
	public void union(int p, int q) {
	    int pRootID = find(p);
	    int qRootID = find(q);
	
	    if(pRootID == qRootID)  return;
	
	    if(size[pRootID] > size[qRootID]) {
	        parent[qRootID] = pRootID;
	        size[pRootID] += size[qRootID];
	    }else {
	        parent[pRootID] = qRootID;
	        size[qRootID] += size[pRootID];
	    }
	    count--;  // 连通分量减一
	}
}

Complexity Analysis

  • time complexity: O ( ) O() ,
  • Space complexity: O ( ) O() ,

Method two: dfs or bfs judgment ring


Complexity Analysis

  • time complexity: O ( ) O() ,
  • Space complexity: O ( ) O() ,
Published 495 original articles · won praise 105 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_43539599/article/details/104867560