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

66 阅读1分钟

leetcode-222.png

这一题,直接用BFS,这种比较耿直的办法可以做出来,就是时间复杂度比较高,是O(n)。

BFS

从上往下,从左往右,一个一个数过去。

var countNodes = function (root) {
    if (!root) return 0
    let queue = [root]
    let sum = 0
    while (queue.length) {
        let size = queue.length
        for (let i = 0; i < size; ++i) {
            let node = queue.shift()
            sum++
            if (node.left) queue.push(node.left)
            if (node.right) queue.push(node.right)
        }
    }
    return sum
};

stack

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
};

优化版

利用满二叉树的性质来做这题。至于满二叉树的性质,大家可以先去查阅一下。
计算左右子树的高度,如果左右子树高度相等,证明左边子树满足满二叉树,那么就计算左子树的个数 + 递归右子树,反之则相反操作。

var countNodes = function (root) {
    if (!root) return 0
    let leftDepth = getDepth(root.left)
    let rightDepth = getDepth(root.right)
    if (leftDepth === rightDepth) {
        return (1 << leftDepth) + countNodes(root.right)
    } else {
        return (1 << rightDepth) + countNodes(root.left)
    }
};

var getDepth = function (node) {
    let depth = 0
    while (node) {
        depth++
        node = node.left
    }
    return depth
}

看下面这图,左子树,也就是结点2,计算出来的高度是2,右子树3的高度也是2,此时计算2这个树的节点数量,也就是 2^2 = 4(顺道把根节点1计算进去),再来递归右子树3

      1
     / \
    2   3
   / \  /
  4  5 6

深度 = 3
节点数 = 6