目录
一、平衡二叉树(力扣110)
实现思想:根据平衡二叉树的定义,平衡二叉树中的每一个节点,它的左右子树的高度差必须小于等于1,根据这个条件我们需要通过遍历得到二叉树的高度。高度是从叶子结点起开始往上数层数。是一个由下向上的过程,每一次得到左右子树的高度再赋给根节点,由此我们需要使用后序遍历来求得二叉树的高度。
class Solution {
public:
int getheight(TreeNode* root){
if (root == nullptr) return 0;
int leftheight = getheight(root->left);
//左子树返回-1说明以该节点为根节点的子树已经不是平衡二叉树
//说明整个二叉树已经不是平衡二叉树直接向上返回-1
if (leftheight == -1) return -1;
int rightheight = getheight(root->right);
//右子树返回-1说明以该节点为根节点的子树已经不是平衡二叉树
//说明整个二叉树已经不是平衡二叉树直接向上返回-1
if (rightheight == -1) return -1;
int result;
//计算当前节点左右子树的高度差是否<1
//如果<1说明以当前节点为根节点的二叉树是平衡二叉树
//反之不是平衡二叉树,返回-1
if (abs(rightheight-leftheight) > 1) result = -1;
else{
//如果是平衡二叉树就计算当前根节点的高度
result = 1+max(leftheight,rightheight);
}
return result;
}
bool isBalanced(TreeNode* root) {
int result = getheight(root);
if (result == -1) return false;
return true;
}
二、二叉树的所有路径(力扣257)
实现思想:这道题目涉及到回溯的过程,每一次遍历完一条路径之后,我们都要将这条路径上的节点弹出去,让新的路径上的节点进来,因此这道题需要十分注意递归时候的每一个操作的顺序。
class Solution {
public:
void traversal(TreeNode* cur, vector<int> &path,vector<string> &result){
path.push_back(cur->val);
//如果识别到下一个节点是空节点就不用继续遍历了,直接返回
if (cur->left == nullptr && cur->right == nullptr){
string sPath;
//此处的循环-1不会将最后一个叶子节点加入到result中,因为循环是path.size()会导致最后结果多一个箭头
for (int i = 0; i < path.size()-1; i++){
sPath += to_string(path[i]);
sPath += "->";
}
//因为前面没有添加最后一个叶子节点,这里要把最后一个叶子节点添加上
sPath += to_string(path[path.size()-1]);
result.push_back(sPath);
return;
}
if (cur->left){
traversal(cur->left,path,result);
//回溯操作
path.pop_back();
}
if (cur->right){
traversal(cur->right,path,result);
//回溯操作
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == nullptr) return result;
traversal(root,path,result);
return result;
}
};
三、左叶子之和(力扣404)
实现思想:直接判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,
class Solution {
public:
int travel(TreeNode* root){
//遇到空节点直接返回
if (root == nullptr) return 0;
//遇到叶子节点直接返回,不写这个返回也可以,只会让递归多进行一层
if (root->left == nullptr && root->right == nullptr) return 0;
//获取左子树左叶子和
int leftnum = travel(root->left);
//判断节点是不是左叶子的条件,注意!!!只有通过父节点才能判断它的子节点是不是左叶子
if (root->left != nullptr && root->left->left == nullptr && root->left->right == nullptr){
leftnum = root->left->val;
}
//获取右子树左叶子和
int rightnum = travel(root->right);
int sum_ = leftnum + rightnum;
return sum_;
}
int sumOfLeftLeaves(TreeNode* root) {
return travel(root);
}
};