一
整个数的最大深度和最高的高度是等价的,因此最简单的思路就是:采取从下往上即后序遍历的方式来计算高度,父节点的高度等于左右孩子节点高度的最大值再加上一,这个时候就需要有返回值来进行向上的传递,总体上是递归的思想。第二种方法是采用层序遍历的方式设置变量进行记录,属于迭代法;第三种方法即深度搜索,从上到下进行遍历。
//方法一 后序遍历
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == nullptr)
return 0;
int lhigh = maxDepth(root->left);
int rhigh = maxDepth(root->right);
int result = max(lhigh,rhigh) + 1;
return result;
}
};
//方法三 先序遍历 深搜
class Solution {
public:
int result = 0;
void dfs(TreeNode* root,int depth){
//终止条件
if(root == nullptr)
return;
//单层递归处理
result = max(result,depth);
depth++;
dfs(root->left,depth);
dfs(root->right,depth);
depth--;//回溯
return;
}
int maxDepth(TreeNode* root) {
if(root == nullptr)
return 0;
dfs(root,1);
return result;
}
};
二 111二叉树最小深度
相比于上一题二叉树的最大深度,最小深度只需要注意保证左右子树是否有叶子节点,即只要左右子树不空,必定会有叶子节点。
//后序遍历
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == nullptr)
return 0;
int lhigh = minDepth(root->left);
int rhigh = minDepth(root->right);
if(lhigh == 0)
return rhigh + 1;
else if(rhigh == 0)
return lhigh + 1;
return min(lhigh,rhigh) + 1;
}
};
//前序遍历 深搜
class Solution {
public:
int result = INT_MAX;
void dfs(TreeNode* root,int depth){
//终止条件
if(root == nullptr)
return;
//单层递归处理
if(root->left == nullptr && root->right == nullptr)
result = min(result,depth);
depth++;
dfs(root->left,depth);
dfs(root->right,depth);
depth--;//回溯
return;
}
int minDepth(TreeNode* root) {
if(root == nullptr)
return 0;
dfs(root,1);
return result;
}
};
三 207 完全二叉树的节点个数
根据完全二叉树的性质,完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满,且叶子节点必定在最左边。则可以进行分类讨论,情况一:节点总数即2^(n-1) 情况二:分别递归左右孩子,直至左右孩子为二叉树,再根据情况一计算
//通用 普通二叉树
class Solution {
private:
int getNodesNum(TreeNode* cur) {
if (cur == NULL) return 0;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
public:
int countNodes(TreeNode* root) {
return getNodesNum(root);
}
};
//完全二叉树
代码
C++
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
if(root == nullptr)
return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 1, rightDepth = 1;
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << (leftDepth-1)) - 1;
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
四 总结
return (2 << (leftDepth-1)) - 1;
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
# 四 总结
1. 树的很多题都需要递归操作,一定要掌握好递归的逻辑。