leetcode222. 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.

计算一个完全二叉树(不是满二叉树)的所有结点数。
这里,我首先想到的是一个求解二叉树结点数的通法,也就是如下的代码:

int count(TreeNode* root)
{
    if(root==NULL) return 0; //Nothing to count
    return 1+count(root->left())+count(root->right());
}

这个算法可通用的所有二叉树,时间复杂度为:

O(n)

在这道题中明显会超时,原因是我们并没有用上完全二叉树的特性,上面题目描述的完全二叉树的特性如下:
1.除最后一层叶子结点以外,所有层的结点数都是满的。2.最后一层叶子结点的结点尽可能的靠近左边,即把左边占满。
那么根据这个特性,可以知道,对于一个结点来说,只要它满足左子树的深度等于右子树的深度。那么,就知道该树的结点数为:

20+21+22+2depth1=2depth1

根据这个特性,我们就可以节省不少计算,思路就是:一直递归到左深等于右深,可以得到该子树的结点数,然后相加,代码如下:

class Solution {
public:
    int countNodes(TreeNode* root) {
        if(root==NULL) return 0;
        TreeNode* l=root; TreeNode* r=root;
        int lh=0;int rh=0;
        while(l) {lh++;l=l->left;}
        while(r) {rh++;r=r->right;}
        if(lh==rh) return pow(2,lh)-1;
        return 1+countNodes(root->left)+countNodes(root->right);
    }
};

有意思的是这个算法的复杂度的计算。很明显的是,看最后的递归式:

1+countNodes(root->left)+countNodes(root->right)

可以看出是用分治的策略每次递归的时候对左子树和右子树进行操作,递归的深度明显就为logn.
而每次递归操作分别就是深度变化也就是

logn+(logn1)+(logn2)+....+1

最终结果的式子就为:
T(N)=T(N2)+c1logn=T(N4)+c1logn+c1(logn1)=...=T(1)+c(logn+logn1+logn2+..+1)=lognlogn

关于,O(logn*logn)大还是O(n),这是一个高中问题,这边我图方便直接用matlab画了个函数图比较:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值