【leetcode】222.完全二叉树的节点个数

77 阅读1分钟

leetcode-222.png

计算节点

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
}