完全二叉树的节点个数
原题在这里:
概述题意,要求比O(n)复杂度更好的求出完全二叉树的节点数量的算法。

struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} };
analyse:
1.利用完全二叉树的性质,分类讨论:

class Solution { int dfs(TreeNode *n) { int ans = 0; while (n != nullptr) { n = n->left; ++ans; } return ans; } public: int countNodes(TreeNode *root) { /* analyse: 利用完全二叉树的性质,分类为4中情况 令左右子树高度分别为lr,那么有: 当l==r时候,左子树一定是满的,那么使用2^l-1求答案 当l!=r时候,右子树一定不满,那么使用2^r-1求答案 */ if (!root) return 0; int l = dfs(root->left); //左子树深度 int r = dfs(root->right); //右子树深度 if (l == r) return (1 << l) + countNodes(root->right); //如果相同,则往右取 return (1 << r) + countNodes(root->left); //否则往左取 } };
2.如上的另一种写法:

class Solution { int leftDepth(TreeNode *root) { return root ? 1 + leftDepth(root->left) : -1; } public: int countNodes(TreeNode *root) { /* analyse: 利用完全二叉树的性质,分类为4中情况 令左右子树高度分别为lr,那么有: 当l==r时候,左子树一定是满的,那么使用2^l-1求答案 当l!=r时候,右子树一定不满,那么使用2^r-1求答案 另一种写法。 */ if (!root) return 0; int d = leftDepth(root), res = 0; while (root) { // cout << "访问节点:" << root->val << endl; int rd = leftDepth(root->right); //右子树深度r与当前深度n的关系只有 n=r+1 or n = r if (d == rd + 1) { //右子树深度小,右走 // cout << " +=" << (1 << d) << endl; res += 1 << d; root = root->right; } else { //两子树深度相同,左走 // cout << " +=" << (1 << (d - 1)) << endl; res += 1 << (d - 1); root = root->left; } --d; // crutial, reduce total depth for subtree } return res; } };
3.另外一种思路是用二分搜索节点,因为二分搜索的细节原因(懂的都懂,不懂的也不多说),就不写了。
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!