刚刚又刷了一道题,感觉难度适中,现在就和大家分享一下经验吧!
题目如下:
Given a complete binary tree, count the number of nodes.
Note:
Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
Example:
Input:
1
/ \
2 3
/ \ /
4 5 6
Output: 6
题意分析:
给定一个完全二叉树,计算树中节点的数目。
注:
完全二叉树定义:除了最后一层,所有层的节点数达到最大,与此同时,最后一层的所有节点都在最左侧(是堆的底层实现);
满二叉树定义:所有层的节点数达到最大。
方法一(层序遍历法)
用res记录遍历二叉树每层节点数之和,在遍历完所有层数后将res的累加值返回,即为二叉树所有节点的数目。
解题代码如下:
class Solution{
public:
int countNodes(TreeNode* root){
queue<TreeNode*> q;
int res = 0;
if(!root) return 0;
q.push(root);
while(!q.empty()){
res = res + q.size();
for(int i = q.size(); i > 0; i--){
TreeNode* temp = q.front(); q.pop();
if(temp->left) q.push(temp->left);
if(temp->right) q.push(temp->right);
}
}
return res;
}
};
提交后的结果如下:
方法二(堆栈法DFS)
为了省时省力这里依旧以前序遍历为例来解决本题。采用前序遍历同时对给定二叉树进行遍历,并用res记录下循环的次数并返回,即为所求的二叉树所有节点的数目。
解题代码如下:
class Solution{
public:
int countNodes(TreeNode* root){
stack<TreeNode*> s;
int res = 0;
if(!root) return 0;
s.push(root);
while(!s.empty()){
res++;
TreeNode* temp = s.top(); s.pop();
if(temp->right) s.push(temp->right);
if(temp->left) s.push(temp->left);
}
return res;
}
};
提交后的结果如下:
方法三(递归法①)
首先分别计算以当前节点为根节点的左子树和右子树的高度并对比,若相等则说明是满二叉树(特殊的完全二叉树),可直接通过公式计算得到节点个数,若不相等则节点个数为左子树的节点个数加上右子树的节点个数再加1(因为需要考虑根节点),其中可以采用递归法来计算左右子树的节点个数。
解题代码如下:
class Solution {
public:
int countNodes(TreeNode* root) {
int hLeft = LeftHeight(root);
int hRight = RightHeight(root);
if (hLeft == hRight) return pow(2, hLeft) - 1;
return countNodes(root->left) + countNodes(root->right) + 1;
}
int LeftHeight(TreeNode* root) {
if (!root) return 0;
return LeftHeight(root->left) + 1;
}
int RightHeight(TreeNode* root) {
if (!root) return 0;
return RightHeight(root->right) + 1;
}
};
提交后的结果如下:
方法四(递归法②)
与方法三的思路大体相同,只是实现方式略有不同而已。
解题代码如下:
class Solution {
public:
int countNodes(TreeNode* root) {
int hLeft = 0, hRight = 0;
TreeNode *pLeft = root, *pRight = root;
while (pLeft) {
++hLeft;
pLeft = pLeft->left;
}
while (pRight) {
++hRight;
pRight = pRight->right;
}
if (hLeft == hRight) return pow(2, hLeft) - 1;
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。