LeetCode 104 二叉树的最大深度
题目描述
给定一个二叉树,找出其最大深度
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例
给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回它的最大深度 3 。
题目解析
对于学过数据结构的可能这道题很快就能使用递归的方式写出来了。树的深度也就是树的高度,计算的时候一般可以使用深度优先搜索的方式递归遍历树结构,当然使用递归的方式也能够使用栈的方式进行实现。下面是两种实现方式:
-
使用递归
对于任意一个节点,如果其左右子树为空,则表明该树只有一个节点,返回1。否则,递归比较左右子树的大小,去最大值再加上1(表示该树的根节点),代码如下:
public int maxDepth(TreeNode root) { if (root == null) { return 0; } if (root.left == null && root.right == null) { return 1; } return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; //比较左右子树深度的最大值再加上该根节点 }
程序运行结果:
-
使用栈结构的非递归方法:
对于非递归的方法,使用队列也是可以的,队列对应的思想是广度优先搜索,或者说是树的层次遍历,而深度优先搜索改成非递归的方式就要采用栈结构了,毕竟递归本身也是使用系统栈结构来实现的。
具体思路如下:
- 创建一个空栈,将树根进栈;
- 栈不为空的时候循环遍历栈,每次查看(注意不是弹出)栈顶指针指向的元素,如果栈顶节点的左右子树为空,则将该栈顶出栈(相对应于递归的时候返回改成递归操作),树的深度-1,继续循环;
- 如果栈顶节点存在左子树,则将左子树入栈,并且将栈顶指针的左孩子置为空,避免下次又重新将该左子树进栈。树的深度加1,继续循环遍历;
- 如果栈顶节点存在右子树,则将右子树入栈,并且将栈顶指针的右孩子置空,树的深度+1;继续循环遍历。
由于在实现的时候树的深度不能够多次累加,所以设置了一个最大的深度来记录当前遍历到的树的最大深度。以示例进行图示说明:
代码如下:
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
Stack<TreeNode> stack = new Stack<>();
stack.add(root);
int deep = 1;
int maxDeep = 1;
while (!stack.empty()) {
TreeNode peek = stack.peek(); //peek为查看栈顶指针
if (peek.left == null && peek.right == null) { //叶子节点将栈顶出栈
deep--;
stack.pop();
continue;
}
if (peek.left != null) { //先查看左子树,就跟递归遍历左子树一样
stack.add(peek.left);
peek.left = null;
deep++;
if (deep > maxDeep) { //有更大的深度则更改最大深度的值
maxDeep++;
}
continue;
}
if (peek.right != null) {
stack.add(peek.right);
peek.right = null;
deep++;
if (deep > maxDeep) {
maxDeep++;
}
}
}
return maxDeep;
}
然而。。。程序运行的好像不是那么理想。。。