【一天一大 lee】完全二叉树的节点个数 (难度:中等) - Day20201124

20201124

题目:

给出一个完全二叉树,求出该树的节点个数。

说明:

完全二叉树的定义如下:
在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。
若最底层为第 h 层,则该层包含 1~  2 h 2^h 2h  个节点。

示例:

输入:
    1
   / \
  2   3
 / \  /
4  5 6

输出: 6

抛砖引玉

在本题中按部就班的遍历二叉树是一定可以统计出所有二叉树节点的。

广度优先遍历:

抛砖引玉

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var countNodes = function(root) {
    if (root == null) return 0
    let queue = [root],
        _result = 1
    while (queue.length) {
        let node = queue.pop()
        if (node.left) {
            queue.push(node.left)
            _result++
        }
        if (node.right) {
            queue.push(node.right)
            _result++
        }
    }
    return _result
}

递归

遍历二叉树还有深度优先遍历的递归方案,鉴于本题要求传入二叉树返回二叉树节点数,则可以直接实现统计二叉树节点的递归逻辑:

  • 传入二叉子树
  • 如果子树为空节点数为 0
  • 如果子树存在左子树或右子树则节点数+1,继续递归求左子树节点数和右子树节点数
var countNodes = function(root) {
    if (root == null) return 0
    return 1 + countNodes(root.left) + countNodes(root.right)
}

单独统计底层节点数

根据题目完全二叉树定义,知道二叉树的层级,那么除了最后一层二叉树的节点数其实是确定的,那么这个问题就可以看出两个部分:

  • 前 level-1 层数量,数学问题:1+2+4…+n+2n = 2**(level-1) - 1
  • 第 level 逐个遍历统计
var countNodes = function(root) {
    if (!root) return 0

    let count = { level: 1, done: false },
        level = 1,
        _result = 0,
        node = root
    while (node.left || node.right) {
        level++
        node = node.left || node.right
    }
    // 前 level-1 层数量(注意:如果level-1最小为1)
    _result = 2 ** (level - 1 || 1) - 1
    // 第 level 逐个遍历统计
    get_end_num(root, 1)
    // (root,层数)
    function get_end_num(node, itemLevel) {
        if (itemLevel + 1 === level) {
            if (node.right) _result++
            if (node.left) _result++
        } else {
            if (node.left) get_end_num(node.left, itemLevel + 1)
            if (node.right) get_end_num(node.right, itemLevel + 1)
        }
    }
    return _result
}

博客: 前端小书童

每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目
欢迎关注留言

公众号:前端小书童

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值