题目描述
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。(本题是剑指Offer第55题)
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
提示:
节点总数 <= 10000
广度优先搜索BFS
采用BFS可以按层来遍历的特点。通过队列FIFO的特性,遍历每一层的元素,计数器值+1。
这里的关键点在于如何遍历每一层的元素:
- 初始化队列deque,计数器k。
- 添加根节点到quene,while循环遍历quene。
- quene中元素个数为n,遍历前n个节点,依次弹出节点,并添加起左右子节点。
- 遍历一层,k值+1,quene为null,返回k值。
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int k = 0;
Deque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
while (!deque.isEmpty()) {
k++;
for (int i = deque.size() - 1; i >= 0; i--) {
TreeNode node = deque.poll();
if (node.left != null) deque.offer(node.left);
if (node.right != null) deque.offer(node.right);
}
}
return k;
}
- 时间复杂度:O(N) N为树的节点数量,BFS需要遍历树的每一个节点。
- 空间复杂度:O(N) 队列存储的最大元素为(N/2)
后续遍历
当二叉树只存在根节点时,二叉树的深度为1。当只存在左子树时,二叉树的深度为左子树的深度+1,当只存在右子树时,二叉树的深度为右子树的深度+1。当左右子树都存在时,则二叉树的深度是左右子树深度的最大值+1。可以很明显的看出使用递归可以比较容易实现。
这里的关键点在于递归什么时候返回?
- 当节点为null时,表示越过了叶子节点,返回 0。
- 当左子树不为null时,左子树可以表示为:
maxDepth1(root.left)+1
。 - 当右子树不为null时,右子树可以表示为:
maxDepth1(root.right)+1
。
public int maxDepth1(TreeNode root) {
if (root == null) return 0;
return Math.max(maxDepth1(root.left), maxDepth1(root.right)) + 1;
}
- 时间复杂度:O(N) N为树的节点数量,递归需要遍历树的每一个节点。
- 空间复杂度:O(N)
总结
本题考察的是二叉树,如果对树的后序遍历或者广度优先搜索比较熟悉,就没啥难度。递归解法,需要抽象出树的深度是由子树的深度决定的,进而引出递归的解法。