LeetCode 222. Count Complete Tree Nodes

问题描述

  • Given a complete binary tree, count the number of nodes.
  • Definition of a complete binary tree from Wikipedia:
    In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
  • 地址

问题分析

  • 给定一棵完全二叉树,求所有节点的个数。
  • 首先,用 DFS做,O(n) 的时间复杂度,TLE。
  • 注意,题干说的是完全二叉树,势必会用到完全二叉树的性质,完全二叉树如果去掉最后一层,那么就是一颗满二叉树,满二叉树的节点个数,可以用2^height - 1直接得到。
    而且,如果一棵树是非满二叉树的完全二叉树,那么它的左子树与右子树中,必有一个是非满二叉树的完全二叉树,一个是满二叉树。
    综上,如果我们用leftMostrightMost分别沿着二叉树的最左边和最右边走,并记录高度height,直到rightMost走到null。此时检查leftMost是否也到null,若是,则说明是一颗满二叉树,直接公式求个数。如果不是,则对左右子树递归求个数,然后相加。
  • 时间复杂度分析:若整体个数为n,那么走到null为 logN, 然后递归左右子树,一个递归是非满二叉树的完全二叉树,肯定为 T(N/2),另一个递归是满二叉树,为logN.所以
T(N) = T(N/2) + 2log(N)
T(N/2) = T(N/4) + 2log(N)
...
T(N) = log(N)*log(N)

经验教训

  • 完全二叉树与满二叉树

代码实现

  • 方法1:
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        TreeNode leftMost = root;
        TreeNode rightMost = root;
        int height = 0;
        while(rightMost != null) {
            leftMost = leftMost.left;
            rightMost = rightMost.right;
            ++height;
        }
        return leftMost == null ? (1 << height) - 1 : 1 + countNodes(root.left) + countNodes(root.right);
    }
  • 方法2:比1更快,但复杂度相同
    public int countNodes(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int halfTreeNum = 1;
        TreeNode leftMost = root.left;
        TreeNode rightMost = root.left;
        while (rightMost != null) {
            leftMost = leftMost.left;
            rightMost = rightMost.right;
            halfTreeNum = halfTreeNum << 1;
        }
        return leftMost == null ?  halfTreeNum + countNodes(root.right) : halfTreeNum + countNodes(root.left);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值