计算节点
BFS
其实这里的内层循环也没必要写,不必要细致到层次遍历,去掉内层循环也可
var countNodes = function (root) {
if (!root) return 0
let stack = [root]
let cnt = 0
while (stack.length) {
let size = stack.length
for (let i = 0; i < size; ++i) {
let node = stack.pop()
cnt++
if (node.left) stack.push(node.left)
if (node.right) stack.push(node.right)
}
}
return cnt
};
简化版本
var countNodes = function (root) {
if (!root) return 0
let stack = [root]
let cnt = 0
while (stack.length) {
let node = stack.pop()
cnt++
if (node.left) stack.push(node.left)
if (node.right) stack.push(node.right)
}
return cnt
};
DFS
var countNodes = function (root) {
if (!root) return 0
let left = countNodes(root.left)
let right = countNodes(root.right)
return left + right + 1
};
上述的解法还没有涉及到一个问题,就是题目中所提及的完全二叉树,完全二叉树是什么呢?
简而言之就是每一层都是满的,不能缺少,如果要有缺少,只能是最后一层的右边缺少
有了这种性质之后,就可以来优化代码了
// 满二叉树
1
/ \
2 3
/ \ / \
4 5 6 7
// 完全二叉树
1
/ \
2 3
/ \ /
4 5 6
var countNodes = function (root) {
if (!root) return 0
let left = treeDepth(root.left)
let right = treeDepth(root.right)
if (left === right) {
// 左右子树高度相等,那么就说明一个问题
// root.left 肯定是满的,而且高度是最大的
// root.right 不详,继续countNodes递归即可
return (1 << left) + countNodes(root.right)
} else {
// 左右子树高度不相等,只能说明
// root.left 可能不是满二叉树,继续countNodes递归即可
// root.right 一定是满二叉树,但是高度肯定不是最大高度
return (1 << right) + countNodes(root.left)
}
};
var treeDepth = function (root) {
let depth = 0
while (root) {
depth++
root = root.left
}
return depth
}