题目 01 - 求二叉树的最大深度
原题链接
题目描述
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
输入示例
思路 01 - 递归
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的就是高度。
- 二叉树节点的深度: 指从根节点到该节点的最长简单路径边的条数或者节点数目
(取决于深度从 0 开始还是从 1 开始) - 二叉树节点的高度: 指从该节点到叶子节点的最长简单路径边的条数或者节点数目
(却决于高度从 0 开始还是从 1 开始)
根节点的高度就是二叉树的最大深度
使用后序遍历实现
代码实现
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return getDepth(root);
}
//递归求最大深度;按照后序遍历的顺序: 左右根
public int getDepth(TreeNode root) {
if(root == null) {
return 0;
}
//递归得到左子树的最大深度
int leftDepth = getDepth(root.left);
//递归得到右子树的最大深度
int rightDepth = getDepth(root.right);
//树最大深度为左右子树中的最大深度 + 1
int depth = 1 + Math.max(leftDepth, + rightDepth);
return depth;
}
}
执行结果
-
时间复杂度:
O(N) -
空间复杂度:
O(N)
精简版本
class Solution {
//递归求最大深度
public int maxDepth(TreeNode root) {
//如果当前节点为空
if(root == null) return 0;
//最大深度为左右子树的最大值 + 根节点本身的深度 (1)
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
思路 02 - 前序遍历实现深度回溯递归
- 前序遍历,根左右
- 每层更新比较当前深度和记录的最大深度,使用
Math.max()更新 - 每层递归,如果左右子树其中有不为
null; 深度+ 1 - 但是如果返回上一层递归,去上一层的递归查找其右子树的深度,需要将当前层的深度减小
代码实现
//起始深度标记为 1
class Solution {
int result;
public int maxDepth(TreeNode root) {
if (root == null)
return 0;
int depth = 1; // 根节点默认深度为 1
getDepth(root, depth);
return result;
}
public void getDepth(TreeNode node, int depth) {
// 递归返回条件
if (node == null) {
return;
}
// 更新最大深度
result = Math.max(depth, result);
// 若左子树不为空,更新当前深度
if (node.left != null) {
getDepth(node.left, depth + 1);
}
// 若右子树不为空,更新当前深度
if (node.right != null) {
getDepth(node.right, depth + 1);
}
}
}
//起始深度标记为 0
class Solution {
int result;
public int maxDepth(TreeNode root) {
if (root == null)
return 0;
int depth = 0; // 起始深度为 0
getDepth(root, depth);
return result;
}
public void getDepth(TreeNode node, int depth) {
// 递归返回条件
if (node == null) {
return;
}
// 当前层存在节点,更新最大深度
depth++;
result = Math.max(depth, result);
// 若左子树不为空
if (node.left != null) {
getDepth(node.left, depth);
}
// 若右子树不为空
if (node.right != null) {
getDepth(node.right, depth);
}
}
}
执行结果
-
间复杂度:
O(N) -
空间复杂度:
O(N)
思路03 - 迭代方式
使用层序遍历,最大深度就是二叉树的层数,和层序遍历的思路一致
优点:好理解
代码实现
class Solution {
//递归求最大深度
public int maxDepth(TreeNode root) {
//如果当前节点为空
if(root == null) return 0;
//模拟队列
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 0;
while(!queue.isEmpty()) {
int size = queue.size();
depth++;
for(int i = 0; i < size; i++) {
TreeNode tmp = queue.pop();
//如果左右子树不为空,需要更新最大高度
if(tmp.left != null) queue.offer(tmp.left);
if(tmp.right != null) queue.offer(tmp.right);
}
}
return depth;
}
}
执行结果
- 时间复杂度:
O(N) - 空间复杂度:
O(N)
题目 02 - 求 N 叉树的最大深度
原题链接
题目描述
给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔。
输入示例
思路 - 递归实现
代码实现 - 传入起始深度为 0
class Solution {
int ans; // 记录最大深度
public int maxDepth(Node root) {
if (root == null) {
return 0;
}
int depth = 0; //起始深度传入为 0
getMaxDepth(root, depth);
return ans;
}
public void getMaxDepth(Node node, int depth) {
if (node == null) {
return;
}
depth++; // 更新最大深度
ans = Math.max(ans, depth);
if (node.children != null && !node.children.isEmpty()) {
// 如果子节点不为空,继续递归更新深度
for (Node c : node.children) {
getMaxDepth(c, depth);
}
}
}
}
代码实现 - 传入起始深度为 1
class Solution {
int ans; // 记录最大深度
public int maxDepth(Node root) {
if (root == null) {
return 0;
}
int depth = 1; //起始深度传入为 0
getMaxDepth(root, depth);
return ans;
}
public void getMaxDepth(Node node, int depth) {
if (node == null) {
return;
}
ans = Math.max(ans, depth);
if (node.children != null && !node.children.isEmpty()) {
// 如果子节点不为空,继续递归更新深度
for (Node c : node.children) {
//由于传入起始深度为 1, depth 已经表示当前层深度; 下一层更新为 depth + 1
getMaxDepth(c, depth + 1);
}
}
}
}
代码实现 - 递归
class Solution {
public int maxDepth(Node root) {
//检查输入
if(root == null) {
return 0;
}
//单层递归逻辑; 递归找到最大深度的节点
int depth = 0;
List<Node> children = root.children;
for(Node n : children) {
depth = Math.max(maxDepth(n), depth);
}
//从最大深度开始返回;最终加上根节点自身的深度 1
return depth + 1;
}
}
执行结果
时间复杂度: O(N)
空间复杂度: O(H)
思路 - 迭代
层序遍历思路。每一层遍历深度 + 1
代码实现
class Solution {
public int maxDepth(Node root) {
//检查输入
if(root == null) {
return 0;
}
//单层递归逻辑; 递归找到最大深度的节点
Deque<Node> queue = new LinkedList<>();
queue.offer(root);
int depth = 0; //记录最大深度
while(!queue.isEmpty()) {
int size = queue.size();
depth++;
//遍历所有含有children的子节点
for(int i = 0; i < size; i++) {
Node tmp = queue.pop();
if(null != tmp.children) {
//加入其下的子节点
for(Node c : tmp.children) {
queue.offer(c);
}
}
}
}
return depth;
}
}
执行结果
- 时间复杂度:
O(N) - 空间复杂度:
O(N)