1. 题目
要求:时间复杂度低于O(N),N为这棵树的节点个数
2. 思路
思路:因为满树的节点数 2 h − 1 2^{h} - 1 2h−1
如果一个节点的右子树的最左节点到达完全二叉树的最后一层,则左子树为满树,节点个数等于左子树的节点数+递归求右子树的节点数+本节点,如果此节点的右子树的最左节点没有到完全二叉树的最后一层,则右子树为满树,节点个数等于右子树的节点数+递归求左子树的节点+本节点。
3. 代码
#include <iostream>
#include <stack>
struct Node {
int value;
Node* left;
Node* right;
Node(int value):
value(value), left(nullptr), right(nullptr) {}
};
void preOrderRecur(Node* head) {
if (head == nullptr) {
return;
}
std::cout << head->value << ",";
preOrderRecur(head->left);
preOrderRecur(head->right);
}
int getMostLevel(Node* node, int curlevel) {
while (node != nullptr) {
curlevel++;
node = node->left;
}
return curlevel - 1;
}
int cbtNode(Node* node, int curlevel, int depth) {
if (curlevel == depth) {
return 1;
}
if (getMostLevel(node->right, curlevel + 1) == depth) {
return (1 << (depth - curlevel)) + cbtNode(node->right, curlevel + 1, depth);
} else {
return (1 << (depth - curlevel - 1)) + cbtNode(node->left, curlevel + 1, depth);
}
}
int cbtTotalNode(Node* head) {
if (head == nullptr) {
return 0;
}
return cbtNode(head, 1, getMostLevel(head, 1));
}
int main() {
Node* head = new Node(1);
head->left = new Node(2);
head->right = new Node(3);
head->left->left = new Node(4);
head->left->right = new Node(5);
head->right->left = new Node(6);
std::cout << "==============recursive==============";
std::cout << "\npre-order: ";
preOrderRecur(head);
std::cout << "\n";
int cbt_total_nodes = cbtTotalNode(head);
std::cout << cbt_total_nodes << std::endl;
return 0;
}
注意:
这里代码return (1 << (depth - curlevel)) + cbtNode(node->right, curlevel + 1, depth);
不能写成return 1 << (depth - curlevel) + cbtNode(node->right, curlevel + 1, depth);
注意不能少一层括号,因为运算符的优先级等问题。
4. 参考
刷题虽然辛苦,但是总算把今天的任务完成了,下一次可能就是写哈希表相关的啦。