1. The maximum depth of the binary tree
Maximum Depth of Binary Tree
Given a binary tree root, return its maximum depth.
The maximum depth of a binary tree is the number of nodes on the longest path from the root node to the furthest leaf node.
1.1 Recursion
It can be seen from the above steps that the depth depends on the left and right subtrees. As long as the left subtree exists, the height will be +1, or if there is a right subtree, you only need to calculate the height of the left and right subtrees, and then compare the heights and then add 1 That's it.
public int maxDepth(TreeNode root) {
if(root==null) return 0;
int leftHight = maxDepth(root.left);
int rightHight = maxDepth(root.right);
return Math.max(leftHight,rightHight)+1;
}
1.2 Layer order traversal
It is relatively simple, you only need to add 1 to the result each time you traverse, and it is generally a hierarchical traversal operation.
public int maxDepth(TreeNode root) {
if(root==null) return 0;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
// 计算深度
int res =0 ;
while(!queue.isEmpty()){
// 每一层的元素数
int size = queue.size();
while(size>0){
TreeNode node = queue.poll();
if(node.left!=null){
queue.offer(node.left);
}
if(node.right!=null){
queue.offer(node.right);
}
size--;
}
res++;
}
return res;
}
2. Balanced binary tree
Balanced Binary Tree
Given a binary tree, determine whether it is a height balanced binary tree.
In this question, a height-balanced binary tree is defined as:
the absolute value of the height difference between the left and right subtrees of each node of a binary tree does not exceed 1.
2.1 Top-down recursion
First, the binary tree needs to be divided into left and right trees, and then the heights of the left and right trees are calculated separately. As long as there are child nodes, the height will be +1.
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
// 左树的高度
int leftHight =getTreeHight(root.left);
// 右树的高度
int rightHight =getTreeHight(root.right);
// 判断高度差,递归
return Math.abs(leftHight-rightHight)<=1 && isBalanced(root.left) && isBalanced(root.right);
}
// 获取当前节点的高度
public int getTreeHight(TreeNode node){
if(node == null) return 0;
int leftHight = getTreeHight(node.left);
int rightHight=getTreeHight(node.right);
return Math.max(leftHight,rightHight)+1;
}
At the beginning, I wanted to use layer order traversal, but I didn't consider the situation of left and right subtrees. However, the above recursion is used from top to bottom to calculate all heights. Time complexity: O(n^2), which is wasteful performance.
2.2 Bottom-up recursion
The advantage of this method is similar to post-order traversal, the way of left and right roots, the leftmost element is the first, and if there are right subtrees that belong to the same tree side by side, or there is no right subtree at present, then it is considered balanced. Then continue to recurse until the height does not meet, exit.
public boolean isBalanced(TreeNode root) {
return getTreeHight(root) >=0;
}
// 获取当前节点的高度
public int getTreeHight(TreeNode root){
if(root == null) return 0;
int leftHight = getTreeHight(root.left);
int rightHight = getTreeHight(root.right);
// 不满足条件leftHight=-1标识没有左子树,rightHight=-1类似
if(leftHight == -1 || rightHight == -1 || Math.abs(leftHight-rightHight)>1){
return -1;
}else{
return Math.max(leftHight,rightHight)+1;
}
}
3. The minimum depth of the binary tree
Minimum Depth of Binary Tree
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes on the shortest path from the root node to the nearest leaf node.
Note: A leaf node refers to a node that has no child nodes.
Input: root = [3,9,20,null,null,15,7]
Output: 2
3.1 Recursion
First, the left and right children are all empty, which means they are leaf nodes. When one of the left and right nodes is empty, it returns 1,
which means that the required depth is the depth of another subtree + 1.
When both left and right nodes exist, a smaller depth is selected.
public int minDepth(TreeNode root) {
if(root == null) return 0;
// 只有根节点,此时就是叶子节点
if(root.left==null && root.right == null) return 1;
// 左子树深度
int leftLength = minDepth(root.left);
// 右子树深度
int rightLength = minDepth(root.right);
// 树的深度:非空子树的深度加上根节点本身,只要有一个子树为空,那么其对应的深度就是0
if(root.left == null || root.right == null) return leftLength+rightLength+1;
// 左右子树都不为空,深度就是左右子树较小的加上本身
return Math.min(leftLength,rightLength)+1;
}
3.2 Layer order traversal
Layer-order traversal is easier to understand. It just needs to judge whether it is a leaf node. If it is a leaf node, it will directly return the current depth. If not, continue to add.
public int minDepth(TreeNode root) {
if(root ==null) return 0;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
int minLength =0;
while(!queue.isEmpty()){
int size = queue.size();
minLength++;
for(int i=0;i<size;i++){
TreeNode node =queue.remove();
// 遇到叶子节点就返回
if(node.left==null && node.right==null){
return minLength;
}
if(node.left!=null){
queue.add(node.left);
}
if(node.right!=null){
queue.add(node.right);
}
}
}
return 0;
}
Compared with recursion, layer-order traversal is an event, and the space is faster, because it only needs to satisfy that the subtrees of the corresponding tree nodes are empty, which means that the leaf node is found, and the depth is returned, and the first leaf node will be found in the end. If it is empty, then there is no need to traverse all binary trees.
4. The maximum depth of an N-ary tree
Maximum Depth of N-Ary Tree
Given an N-ary tree, find its maximum depth.
The maximum depth refers to the total number of nodes on the longest path from the root node to the furthest leaf node.
The N-ary tree input is serialized in level-order traversal, with each set of child nodes separated by a null value (see example).
4.1 Layer order traversal
This question is similar to a binary tree, the difference is that you need to traverse the sub-elements and then add sub-elements.
public int maxDepth(Node root) {
if(root == null) return 0;
LinkedList<Node> queue = new LinkedList<>();
queue.add(root);
int minLength = 0;
while(!queue.isEmpty()){
int size = queue.size();
minLength++;
for(int i=0;i<size;i++){
Node node = queue.poll();
List<Node> children = node.children;
for(Node child:children){
queue.add(child);
}
}
}
return minLength;
}
4.2 Recursion
public int maxDepth(Node root) {
if(root == null)
{
return 0;}
else if(root.children.isEmpty())
{
return 1;}
else{
List<Integer> hight = new ArrayList<>();
List<Node> children = root.children;
for(Node child:children){
hight.add(maxDepth(child));
}
return Collections.max(hight)+1;
}
}
Summarize
Regarding the depth and height of binary trees, using recursion is very fast, but the disadvantage is that you need to consider the boundaries. Sometimes you can’t think of a recursive solution. Recursion is still not familiar, and layer order traversal is easy to understand and think of, but the disadvantages The reason is that the code is relatively long.