后序遍历:得到左子树信息,右子树信息,中进行操作赋值给该节点
一、平衡二叉树
题目链接/文章讲解/视频讲解: 代码随想录
1.平衡二叉树:左右子树高度之差小于1
2.引入了一个bool的判断值,其实是可以不用的
代码:
class Solution {
public:
int depth(TreeNode* root,bool &result)
{
if(!root) return 0;
int l=depth(root->left,result);
int r=depth(root->right,result);
if(l>r+1||l+1<r) result=false;
return 1+max(l,r);
}
bool isBalanced(TreeNode* root) {
bool judge =true;
depth(root,judge);
return judge;
}
};
方法:
可以用-1代表不是平衡二叉树
class Solution {
public:
// 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
int getHeight(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftHeight = getHeight(node->left);
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right);
if (rightHeight == -1) return -1;
return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight);
}
bool isBalanced(TreeNode* root) {
return getHeight(root) == -1 ? false : true;
}
};
二、二叉树的所有路径
题目链接/文章讲解/视频讲解: 代码随想录
1.传递形参,可以避免回溯的代码。
void traversal(TreeNode* cur, string path, vector<string>& result)
2.本题采用前序遍历,因为是一个数值是从上到下的。
3.添加->时要注意,最后一个元素之后是没有->的,所以循环语句是
for(int i=0;i<path.size()-1;i++)
代码:
class Solution {
public:
void traversal(TreeNode* root,vector<int> &path,vector<string> & result)
{
//中
path.push_back(root->val);
//终止情况 到叶子节点了
if(root->left==NULL&&root->right==NULL)
{
string res;
for(int i=0;i<path.size()-1;i++)
{
res+=to_string(path[i]);
res += "->";
}
res+=to_string(path[path.size() - 1]);
result.push_back(res);
return;//返回
}
//左 判断,防止中的时候访问空指针
if(root->left)
{
traversal(root->left,path,result);
//回溯,一个递归一个回溯,
//最后已经添加到result里了,递归一个添加一个元素,回溯删去这个元素
path.pop_back();
}
//右
if(root->right)
{
traversal(root->right,path,result);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> path;
vector<string> result;
if (root == NULL) return result;
traversal(root,path,result);
return result;
}
};
三、左叶子之和
题目链接/文章讲解/视频讲解: 代码随想录
1.本题不难,主要是要思考如何得到要的数据 ,向上传递
利用左叶子节点的规则来判断,得到左叶子节点的数值,向上传递
2.细节:可以增加一个判断,减少递归的层数
if (root->left == NULL && root->right== NULL) return 0;
//其实这个也可以不写,如果不写不影响结果,但就会让递归多进行了一层。
代码:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(!root)
{
return 0;
}
int l=sumOfLeftLeaves(root->left);
//判断该节点的左子节点是否是左子叶节点
if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL)
{
l=root->left->val;
}
int r=sumOfLeftLeaves(root->right);
return l+r;//中,返回上一层
}
};
四、完全二叉树的节点个数
题目链接/文章讲解/视频讲解: 代码随想录
代码: 求解普通二叉树
class Solution {
public:
int countNodes(TreeNode* root) {
if(!root) return 0;
int l=countNodes(root->left);
int r=countNodes(root->right);
return l+r+1;
}
};
1.完全二叉树可以由满二叉树组合而成,如何判断满二叉树
完全二叉树的特性:最后一层节点从左到右,所以可以通过向左的深度和向右的深度判断是否为满二叉树
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0;
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
int leftTreeNum = countNodes(root->left); // 左
int rightTreeNum = countNodes(root->right); // 右
int result = leftTreeNum + rightTreeNum + 1; // 中 左右加一个中间的
return result;
}
};