二叉树的最大和最小深度
二叉树的最大深度
题目描述
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
解题思路
直观的方法是通过递归来解决问题。下面使用 DFS(深度优先搜索)来实现。
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function(root) {
if(root === null) {
return 0;
} else {
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
};
复杂度分析
-
时间复杂度:我们每个结点只访问一次,因此时间复杂度为 O(N), -
空间复杂度:在最糟糕的情况下,树是完全不平衡的,例如每个结点只剩下左子结点,递归将会被调用 N 次(树的高度),因此保持调用栈的存储将是 O(N)。但在最好的情况下(树是完全平衡的),树的高度将是 log(N)。因此,在这种情况下的空间复杂度将是 O(log(N))。
二叉树的最小深度
题目描述
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2.
解题思路
最开始按照求最大深度的去写了 return 1 + Math.min(minDepth(root.left), minDepth(root.right))
,然后 1, 2 这个测试用例没过, 预期是2,但是使用上面的代码执行结果为是1。
再次认真阅读一下题目:
叶子节点是指没有子节点的节点,这句话的意思是 1 不是叶子节点;
题目问的是到叶子节点的最短距离,所以所有返回结果为 1 当然不是这个结果。
我们来认真的整理一下递归的结束条件,分为以下三种情况:
-
左子节点和右子节点都为空的情况,说明到达了叶子节点,直接返回1; -
左子节点和右子节点都不为空的情况,返回左右子节点中最小的深度 + 1; -
左子节点和右子节点其中一个为空的情况,返回不为空的子节点中最小的深度 + 1;
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function(root) {
// 当前节点为空的时候返回0
if(root === null) {
return 0;
}
// 当前为叶子节点,左右节点都为null
if(root.left === null && root.right === null) {
return 1;
} else if(root.left && root.right ){
// 左右子节点都不为 null,深度为当前节点的深度 1 加上左右子节点中最小的深度
return 1 + Math.min(minDepth(root.left), minDepth(root.right))
} else {
// 左右子节点有一个不为空的情况,深度为当前节点的深度 1 加上不为空的子节点中最小的深度
return 1 + minDepth(root.left || root.right);
}
};
复杂度分析
-
时间复杂度:我们每个结点只访问一次,因此时间复杂度为 O(N), -
空间复杂度:在最糟糕的情况下,树是完全不平衡的,例如每个结点只剩下左子结点,递归将会被调用 N 次(树的高度),因此保持调用栈的存储将是 O(N)。但在最好的情况下(树是完全平衡的),树的高度将是 log(N)。因此,在这种情况下的空间复杂度将是 O(log(N))。