二叉树的最小深度(leetcode - 111)
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
思路 (深度优先遍历)
- 声明
deep
记录最小深度 - 使用深度优先遍历树结构
- 如果遇到叶子节点,则记录当前的deep
- 找到所有比当前
deep
层级还少的叶子节点,不断更新最小深度deep
var minDepth = function(root) {
if(!root) return 0;
let deep = 0;
const dfs = (n, l) => {
// 如果deep已经存在,并且当前层级l比deep层级还多,则直接返回deep
if(deep && l >= deep) {
return deep;
}
if(!n.left && !n.right) {
deep = deep ? Math.min(deep, l) : l;
}
if(n.left) dfs(n.left, l+1)
if(n.right) dfs(n.right, l+1)
}
dfs(root, 1)
return deep;
};
复杂度分析:
- 时间复杂度:O(N) N是节点的数量,最坏的情况下每个节点都访问一次
- 空间复杂度:O(H) H是树的高度
思路 (广度优先遍历)
- 声明一个栈
stack
和最小深度deep
- 把根节点或者下一层级的节点(根节点是第一层级)入栈
- 如果当前层级中没有叶子节点,把这一层级的节点全部出栈,
deep
加1 - 重复2、3步骤直至当前层级中有节点为叶子节点,则返回
deep
var minDepth = function(root) {
if(!root) return 0;
const stack = [root]
let deep = 1;
while(stack.length) {
let len = stack.length;
while(len > 0){
const n =stack.shift();
if(!n.left && !n.right) {
return deep
}
if(n.left) stack.push(n.left)
if(n.right) stack.push(n.right)
len--;
}
deep++
}
};
复杂度分析:
- 时间复杂度:O(N) N是节点的数量,最坏的情况下每个节点都访问一次
- 空间复杂度:O(N) 创建了一个栈,最坏的情况下每个节点都入栈
深度优先遍历和广度优先遍历的对比
相比来说,当树结构比较复杂时,广度优先遍历更加适合;
广度优先遍历是按照层级来遍历数据,只要有一个是叶子节点,就不会再继续遍历了;
深度优先遍历按照链条来遍历数据,有一个是叶子节点并不一定就是最小深度,还需要继续深度遍历其他的子树,
所以当数据量很大,树结构复杂时,广度优先遍历可以更快的得出最小深度。