diff --git a/include/s0222_count_complete_tree_nodes.hpp b/include/s0222_count_complete_tree_nodes.hpp new file mode 100644 index 0000000..20ccd8f --- /dev/null +++ b/include/s0222_count_complete_tree_nodes.hpp @@ -0,0 +1,16 @@ +#ifndef S0222_COUNT_COMPLETE_TREE_NODES_HPP +#define S0222_COUNT_COMPLETE_TREE_NODES_HPP + +#include + +#include "structures.hpp" + +using namespace std; + +class S0222 { + public: + int countNodes1(TreeNode* root); + int countNodes2(TreeNode* root); +}; + +#endif diff --git a/src/s0222_count_complete_tree_nodes.cpp b/src/s0222_count_complete_tree_nodes.cpp new file mode 100644 index 0000000..bbf7564 --- /dev/null +++ b/src/s0222_count_complete_tree_nodes.cpp @@ -0,0 +1,38 @@ +#include "s0222_count_complete_tree_nodes.hpp" + +// DFS O(n) +int S0222::countNodes1(TreeNode* root) { + if (root == nullptr) return 0; + return countNodes1(root->left) + countNodes1(root->right) + 1; +} + +// BFS O(n) +int S0222::countNodes2(TreeNode* root) { + queue q; + int sum{0}; + if (root) q.push(root); + TreeNode* front; + int size{0}; + while (!q.empty()) { + size = q.size(); + for (int i{0}; i < size; ++i) { + front = q.front(); + q.pop(); + ++sum; + if (front->left) q.push(front->left); + if (front->right) q.push(front->right); + } + } + return sum; +} + +// 利用满二叉树的特性 +// 假设满二叉树一共有 h 层,那么总节点个数的范围应该是 [2^(h - 1), 2^h - 1] 之间 +// 也就是最后一层满和没满的区别 +// 所以可以在这个范围内用二分法搜索 +// 如何判断第 kkk 个节点是否存在呢?如果第 kkk 个节点位于第 hhh 层,则 kkk +// 的二进制表示包含 h+1h+1h+1 位,其中最高位是 +// 111,其余各位从高到低表示从根节点到第 kkk 个节点的路径,000 +// 表示移动到左子节点,111 表示移动到右子节点。通过位运算得到第 kkk +// 个节点对应的路径,判断该路径对应的节点是否存在,即可判断第 kkk +// 个节点是否存在。