vlambda博客
学习文章列表

力扣222——完全二叉树的节点个数(二分)

力扣222——完全二叉树的节点个数(二分)


简单的做法是遍历,这里不赘述了;


更快的算法是用位运算+二分;


首先可以快速dfs出节点深度h;


对于完全二叉树来说,节点个数为2^h 到 2^(h+1) - 1之间;


并且具备单增性,可以在这个区间内二分答案;


对于二分出的个数,需要check节点个数在该mid之上还是之下;


对于节点个数x,观察其二进制形式,从第二位开始,其实表示的是该叶子节点的路径(0左1右),例如8,在完全二叉树上,是三次取左子树;



实现上跟二分答案代码相似,check函数部分就是判定跟着该路径到达的叶子节点是否存在;


class Solution {private: int level = 0; TreeNode* R;public: int countNodes(TreeNode* root) { R = root; if (root == nullptr) return 0; TreeNode* node = root; while (node->left != nullptr) { level++; node = node->left; } int low = 1 << level, high = (1 << (level + 1)) - 1; while (low <= high) { int mid = (high + low) >> 1; if (check(mid)) low = mid + 1; else high = mid - 1; } return low - 1; }
bool check(int k) { int x = level; auto node = R; while (node != nullptr && x--) { if (k & (1 << x)) node = node->right; else node = node->left; } return node != nullptr; }};