返回介绍

Maximum Depth of Binary Tree

发布于 2025-02-22 13:01:29 字数 5471 浏览 0 评论 0 收藏 0

Source

Problem

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Example

Given a binary tree as follow:

  1
 / \
2   3
   / \
  4   5

The maximum depth is 3 .

题解 - 递归

树遍历的题最方便的写法自然是递归,不过递归调用的层数过多可能会导致栈空间溢出,因此需要适当考虑递归调用的层数。我们首先来看看使用递归如何解这道题,要求二叉树的最大深度,直观上来讲使用深度优先搜索判断左右子树的深度孰大孰小即可,从根节点往下一层树的深度即自增 1,遇到 NULL 时即返回 0。

由于对每个节点都会使用一次 maxDepth ,故时间复杂度为 O(n)O(n)O(n), 树的深度最大为 nnn, 最小为 log2n\log_2 nlog2n, 故空间复杂度介于 O(logn)O(\log n)O(logn) 和 O(n)O(n)O(n) 之间。

C++

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *   int val;
 *   TreeNode *left, *right;
 *   TreeNode(int val) {
 *     this->val = val;
 *     this->left = this->right = NULL;
 *   }
 * }
 */
class Solution {
public:
  /**
   * @param root: The root of binary tree.
   * @return: An integer
   */
  int maxDepth(TreeNode *root) {
    if (NULL == root) {
      return 0;
    }

    int left_depth = maxDepth(root->left);
    int right_depth = maxDepth(root->right);

    return max(left_depth, right_depth) + 1;
  }
};

Java

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *   public int val;
 *   public TreeNode left, right;
 *   public TreeNode(int val) {
 *     this.val = val;
 *     this.left = this.right = null;
 *   }
 * }
 */
public class Solution {
  /**
   * @param root: The root of binary tree.
   * @return: An integer.
   */
  public int maxDepth(TreeNode root) {
    // write your code here
    if (root == null) {
      return 0;
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
  }
}

题解 - 迭代(显式栈)

使用递归可能会导致栈空间溢出,这里使用显式栈空间(使用堆内存) 来代替之前的隐式栈空间。从上节递归版的代码(先处理左子树,后处理右子树,最后返回其中的较大值) 来看,是可以使用类似后序遍历的迭代思想去实现的。

首先使用后序遍历的模板,在每次迭代循环结束处比较栈当前的大小和当前最大值 max_depth 进行比较。

C++

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *   int val;
 *   TreeNode *left, *right;
 *   TreeNode(int val) {
 *     this->val = val;
 *     this->left = this->right = NULL;
 *   }
 * }
 */
class Solution {
public:
  /**
   * @param root: The root of binary tree.
   * @return: An integer
   */
  int maxDepth(TreeNode *root) {
    if (NULL == root) {
      return 0;
    }

    TreeNode *curr = NULL, *prev = NULL;
    stack<TreeNode *> s;
    s.push(root);

    int max_depth = 0;

    while(!s.empty()) {
      curr = s.top();
      if (!prev || prev->left == curr || prev->right == curr) {
        if (curr->left) {
          s.push(curr->left);
        } else if (curr->right){
          s.push(curr->right);
        }
      } else if (curr->left == prev) {
        if (curr->right) {
          s.push(curr->right);
        }
      } else {
        s.pop();
      }

      prev = curr;

      if (s.size() > max_depth) {
        max_depth = s.size();
      }
    }

    return max_depth;
  }
};

题解 3 - 迭代(队列)

在使用了递归/后序遍历求解树最大深度之后,我们还可以直接从问题出发进行分析,树的最大深度即为广度优先搜索中的层数,故可以直接使用广度优先搜索求出最大深度。

C++

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *   int val;
 *   TreeNode *left, *right;
 *   TreeNode(int val) {
 *     this->val = val;
 *     this->left = this->right = NULL;
 *   }
 * }
 */
class Solution {
public:
  /**
   * @param root: The root of binary tree.
   * @return: An integer
   */
  int maxDepth(TreeNode *root) {
    if (NULL == root) {
      return 0;
    }

    queue<TreeNode *> q;
    q.push(root);

    int max_depth = 0;
    while(!q.empty()) {
      int size = q.size();
      for (int i = 0; i != size; ++i) {
        TreeNode *node = q.front();
        q.pop();

        if (node->left) {
          q.push(node->left);
        }
        if (node->right) {
          q.push(node->right);
        }
      }

      ++max_depth;
    }

    return max_depth;
  }
};

Java

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *   public int val;
 *   public TreeNode left, right;
 *   public TreeNode(int val) {
 *     this.val = val;
 *     this.left = this.right = null;
 *   }
 * }
 */
public class Solution {
  /**
   * @param root: The root of binary tree.
   * @return: An integer.
   */
  public int maxDepth(TreeNode root) {
    if (root == null) {
      return 0;
    }

    int depth = 0;
    Queue<TreeNode> q = new LinkedList<TreeNode>();
    q.offer(root);
    while (!q.isEmpty()) {
      depth++;
      int qLen = q.size();
      for (int i = 0; i < qLen; i++) {
        TreeNode node = q.poll();
        if (node.left != null) q.offer(node.left);
        if (node.right != null) q.offer(node.right);
      }
    }

    return depth;
  }
}

源码分析

广度优先中队列的使用中, qLen 需要在 for 循环遍历之前获得,因为它是一个变量。

复杂度分析

最坏情况下空间复杂度为 O(n)O(n)O(n), 遍历每一个节点,时间复杂度为 O(n)O(n)O(n),

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文