Leetcode|二叉树的属性|222. 完全二叉树的节点个数

在这里插入图片描述

在这里插入图片描述

0 初始思路(DFS)

0.1 90%DFS— O ( n ) O(n) O(n)

初看题目,直接思路就是按完全二叉树的性质分两种情况讨论

  • 二叉树是满二叉树(最后一层叶节点没有缺失)
  • 二叉树是非满二叉树(最后一层右侧集中缺失若干叶节点)

但当初没有往深想,只是简单判断整个树若是满二叉树,则用公式 2 h − 1 2^h - 1 2h1来求,其余情况又是时间复杂度为 O ( n ) O(n) O(n)dfs了,此外也没有用到位运算,所以效率大打折扣。

class Solution {
public:
    int dfs(TreeNode* root, int left_high, int cur_high) {
        if (!root && (cur_high == left_high)) return 1;
        if (!root && (cur_high != left_high)) return 0;
        return dfs(root->right, left_high, cur_high + 1) + dfs(root->left, left_high, cur_high + 1);
    }
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        int left_high = 1;
        int right_high = 1;
        auto node_left = root;
        auto node_right = root;
        while (node_right->right) {
            node_right = node_right->right;
            right_high++;
            node_left = node_left->left;
            left_high++;
        }
        if (!node_left->left) return pow(2, left_high) - 1;
        left_high++;
        return pow(2, left_high) - 1 - dfs(root, left_high, 1);
    }
};

0.2 100%DFS— O ( n ) O(n) O(n)

此处就当成普通二叉树的问题去变量了,因此时间复杂度也是 O ( n ) O(n) O(n)

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        int left = countNodes(root->left);
        int right = countNodes(root->right);
        return left + right + 1;
    }
};

在这里插入图片描述

1 位运算 + 运用满二叉树性质快速遍历

在这里插入图片描述

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (!root) return 0;
        int left_high = 0;  // 取0方便求指数
        auto left_node = root;
        auto right_node = root;
        while (right_node->right) {
            right_node = right_node->right;
            left_node = left_node->left;
            left_high++;
        }
        if (!left_node->left) return (2 << left_high) - 1;  // 注意(2<<1) 相当于2^2,所以left_high初始为0
        return countNodes(root->left) + countNodes(root->right) + 1;  // +1是要加上当前root节点
    }
};

在这里插入图片描述

致谢

感谢「代码随想录」公众号梳理的思路,欢迎大家关注这位大佬的公号

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SL_World

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值