二叉树的最小(大)深度问题
二叉树的最小(大)深度问题
作者:Grey
原文地址:
题目描述#
给定一个二叉树,找出其最小深度,最小深度是从根节点到最近叶子节点的最短路径上的节点数量,说明:叶子节点是指没有子节点的节点。
题目链接见:LeetCode 111. Minimum Depth of Binary Tree
本题可以用两种方法来解,第一种方法,使用二叉树的递归套路,第二种方法是 Morris 遍历。
二叉树的递归套路解法#
相关介绍见:使用二叉树的递归套路来解决的问题
定义递归函数
int minDepth(TreeNode head)
递归含义表示:以 head
为头的二叉树的最小深度为多少。
接下来是 base case,显而易见,空树的深度是 0,
if (null == head) {
return 0;
}
接下来是普遍情况:
如果 head 的左树为空,则最小深度就是右树的最小深度加1(这里的加1就是包含头节点);
如果 head 的右树为空,则最小深度就是左树的最小深度加1(这里的加1就是包含头节点);
如果 head 的左右树都不为空,则最小深度就是左右树深度更小的那个加1(这里的加1就是包含头节点)。
完整代码如下
public int minDepth(TreeNode head) {
if (null == head) {
return 0;
}
if (head.left == null) {
return minDepth(head.right) + 1;
}
if (head.right == null) {
return minDepth(head.left) + 1;
}
return Math.min(minDepth(head.left), minDepth(head.right)) + 1;
}
这个解法的时间复杂度是
如果递归栈算空间的话,整个算法空间复杂度就是递归栈的复杂度
类似问题还有,二叉树的最大深度问题:
题目链接见:LeetCode 104. Maximum Depth of Binary Tree
也是用二叉树的递归套路来解,定义递归函数
int maxDepth(TreeNode root)
递归含义表示:以 root
为头的二叉树的最大深度为多少。
接下来是 base case,显而易见,空树的深度是 0,
if (null == root) {
return 0;
}
接下来是普遍情况:
如果 root 的左树为空,则最大深度就是右树的最小深度加 1(这里的加 1 就是包含头节点);
如果 root 的右树为空,则最大深度就是左树的最小深度加 1(这里的加 1 就是包含头节点);
如果 root 的左右树都不为空,则最大深度就是左右树深度更大的那个加 1(这里的加1就是包含头节点)。
完整代码如下:
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
Morris 遍历解法#
使用 Morris 遍历,可以实现空间复杂度达到
本题如果要用Morris遍历,需要解决的第一个问题是Morris发现当前层?
即:假设上一个节点是 X,在第 8 层,下一个遍历的节点是 Y,如何判断 Y 在第几层?
结论是:如果Y左树的最右节点是 A(非 X ),Y 必定是第 9 层,如果 Y 左树的最右节点是 X,那 Y 在第 X 层数-Y 的左树的右节点的个数
需要解决的第二个问题是Morris发现叶节点?
结论是:每个结点第二次回到自己的时候,因为要恢复指针,在恢复后,看下是否是叶子节点, 最后要单独遍历一下左树的最右节点。
完整代码见
public int minDepth(TreeNode head) {
if (head == null) {
return 0;
}
TreeNode cur = head;
TreeNode mostRight;
int curHeight = 0;
int min = Integer.MAX_VALUE;
while (cur != null) {
mostRight = cur.left;
if (mostRight != null) {
int dulplicate = 1;
while (mostRight.right != null && mostRight.right != cur) {
dulplicate++;
mostRight = mostRight.right;
}
if (mostRight.right == null) {
curHeight++;
mostRight.right = cur;
cur = cur.left;
continue;
} else {
if (mostRight.left == null) {
min = Math.min(min, curHeight);
}
curHeight -= dulplicate;
mostRight.right = null;
}
} else {
curHeight++;
}
cur = cur.right;
}
int rightMostHeight = 1;
TreeNode c = head;
while (c.right != null) {
rightMostHeight++;
c = c.right;
}
if (c.left == null) {
min = Math.min(min, rightMostHeight);
}
return min;
}
用 Morris 方法求二叉树的最大深度也是类似,完整代码如下
public int maxDepth2(TreeNode head) {
if (head == null) {
return 0;
}
TreeNode cur = head;
TreeNode mostRight;
int curLevel = 0;
int maxHeight = Integer.MIN_VALUE;
while (cur != null) {
mostRight = cur.left;
if (mostRight != null) {
int rightBoardSize = 1;
while (mostRight.right != null && mostRight.right != cur) {
rightBoardSize++;
mostRight = mostRight.right;
}
if (mostRight.right == null) { // 第一次到达
curLevel++;
mostRight.right = cur;
cur = cur.left;
continue;
} else { // 第二次到达
if (mostRight.left == null) {
maxHeight = Math.max(maxHeight, curLevel);
}
curLevel -= rightBoardSize;
mostRight.right = null;
}
} else { // 只有一次到达
curLevel++;
}
cur = cur.right;
}
int finalRight = 1;
cur = head;
while (cur.right != null) {
finalRight++;
cur = cur.right;
}
if (cur.left == null) {
maxHeight = Math.max(maxHeight, finalRight);
}
return maxHeight;
}
更多#
作者:GreyZeng
出处:https://www.cnblogs.com/greyzeng/p/16963808.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
你可以在这里自定义其他内容
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/16963808.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)