数据结构与算法——Java实现 42.二叉树的最大深度

苦尽甘来时,一路向阳开

                        —— 24.10.21

104. 二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出:2
输入:root = [3,9,20,null,null,15,7]
输出:3

方法1.深度优先搜索算法

思路

递归+后序遍历实现

① 得到左子树深度,得到右子树深度,二者最大者加一,就是本节点深度

② 因为需要先得到左右子树深度,很是然是后序遍历典型应用

③ 关于深度的定义:从根出发,离根最远的节点总边数

注意:力扣里的深度定义要多一

如果我们知道了左子树和右子树的最大深度 l 和 r,那么该二叉树的最大深度即为左右子树的最大深度再加1,即max(l,r)+1

而左子树和右子树的最大深度又可以以同样的方式进行计算。因此我们可以用「深度优先搜索」的方法来计算二叉树的最大深度。具体而言,在计算当前二叉树的最大深度时,可以先递归计算出其左子树和右子树的最大深度,然后在 O(1) 时间内计算出当前二叉树的最大深度。递归在访问到空节点时退出


代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        } else {
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

树1:                                                                      树2:

                      11                                                                1

                 /            \                                                         /      \                                             

            7                 11                                                   1         4  

          /    \              /     \

        5       9         4        5

     /    \     /   \       /  \

   3     6   2    8   9    28   


本地测试代码 

public class LeetCode104BinaryTreeDepth {
    public static int maxDepth(TreeNode root){
        if (root == null) {
            return 0;
        } else {
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }

    public static void main(String[] args) {
        TreeNode root1 = new TreeNode(
                11,
                new TreeNode(7,
                        new TreeNode(5,
                                new TreeNode(3),
                                new TreeNode(6)),
                        new TreeNode(9,
                                new TreeNode(2),
                                new TreeNode(8))
                ),
                new TreeNode(11,
                        new TreeNode(4,
                                new TreeNode(9),
                                new TreeNode(28)),
                        new TreeNode(5)
                )
        );

        TreeNode root2 = new TreeNode(1,
                new TreeNode(1),new TreeNode(4));
        System.out.println("root1_depth:"+maxDepth(root1));
        System.out.println("root2_depth:"+maxDepth(root2));
    }
}

方法2

非递归+后序遍历+栈实现

思路

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public static int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        TreeNode cur = root;
        TreeNode pop = null;
        LinkedList<TreeNode> stack = new LinkedList<>();
        // 栈的最大高度
        int max = 0;
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                stack.push(cur);
                int size = stack.size();
                if (size > max) {
                    max = size;
                }
                cur = cur.left;
            } else {
                TreeNode peek = stack.peek();
                if (peek.right == null || peek.right == pop) {
                    pop = stack.pop();
                } else {
                    cur = peek.right;
                }
            }
        }
        return max;
    }

}

本地测试代码

import java.util.LinkedList;

public class LeetCode104BinaryTreeDepth2 {
    public static int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        TreeNode cur = root;
        TreeNode pop = null;
        LinkedList<TreeNode> stack = new LinkedList<>();
        // 栈的最大高度
        int max = 0;
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                stack.push(cur);
                int size = stack.size();
                if (size > max) {
                    max = size;
                }
                cur = cur.left;
            } else {
                TreeNode peek = stack.peek();
                if (peek.right == null || peek.right == pop) {
                    pop = stack.pop();
                } else {
                    cur = peek.right;
                }
            }
        }
        return max;
    }

    public static void main(String[] args) {
        TreeNode root1 = new TreeNode(
                11,
                new TreeNode(7,
                        new TreeNode(5,
                                new TreeNode(3),
                                new TreeNode(6)),
                        new TreeNode(9,
                                new TreeNode(2),
                                new TreeNode(8))
                ),
                new TreeNode(11,
                        new TreeNode(4,
                                new TreeNode(9),
                                new TreeNode(28)),
                        new TreeNode(5)
                )
        );

        TreeNode root2 = new TreeNode(1,
                new TreeNode(1), new TreeNode(4));
        System.out.println("root1_depth:" + maxDepth(root1));
        System.out.println("root2_depth:" + maxDepth(root2));
    }
}

方法3

思路

层序遍历法,最终遍历过几层,代表深度有多少

使用广度优先搜索(Breadth-First Search,BFS)的思想,通过一个队列逐层遍历二叉树。每遍历完一层,深度加 1,直到队列为空

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // depth遍历统计树的深度
        int depth = 0;
        // Queue队列接口,实现类为链表LinkedList实现
        Queue<TreeNode> queue = new LinkedList<>();
        // 将二叉树加入队列中
        queue.offer(root);
        // int c1 = queue.size(); // 记录每层有几个元素
        // 通过每一层的结点数进行遍历完来判断每一层的分界线
        while (!queue.isEmpty()) {
//            int c2 = 0; // 记录遍历时每一层的孩子数
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode poll = queue.poll(); // 根节点
                // 每次取出元素进行打印
//                System.out.print(poll.value + " ");
                if (poll.left != null) { // 根节点的左孩子
                    queue.offer(poll.left);
//                    c2++;
                }
                if (poll.right != null) { // 根节点的右孩子
                    queue.offer(poll.right);
//                    c2++;
                }
            }
//            c1 = c2;
//            System.out.println();
            depth++;
        }
        return depth;
    }
}

本地测试代码

import java.util.LinkedList;
import java.util.Queue;

public class LeetCode104BinaryTreeDepth3 {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // depth遍历统计树的深度
        int depth = 0;
        // Queue队列接口,实现类为链表LinkedList实现
        Queue<TreeNode> queue = new LinkedList<>();
        // 将二叉树加入队列中
        queue.offer(root);
        // int c1 = queue.size(); // 记录每层有几个元素
        // 通过每一层的结点数进行遍历完来判断每一层的分界线
        while (!queue.isEmpty()) {
//            int c2 = 0; // 记录遍历时每一层的孩子数
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode poll = queue.poll(); // 根节点
                // 每次取出元素进行打印
//                System.out.print(poll.value + " ");
                if (poll.left != null) { // 根节点的左孩子
                    queue.offer(poll.left);
//                    c2++;
                }
                if (poll.right != null) { // 根节点的右孩子
                    queue.offer(poll.right);
//                    c2++;
                }
            }
//            c1 = c2;
//            System.out.println();
            depth++;
        }
        return depth;
    }

    public static void main(String[] args) {
        TreeNode root = new TreeNode(1,
                new TreeNode(2,
                        new TreeNode(4),
                        new TreeNode(5,
                                new TreeNode(7), null)),
                new TreeNode(3,
                        null,
                        new TreeNode(6)));
        System.out.println(new LeetCode104BinaryTreeDepth3().maxDepth(root));
    }
}

上一篇:Hadoop---HDFS(2)


下一篇:【Java后端】之 ThreadLocal 详解