1. 平衡二叉树 (回溯遍历, 从下到上递归是高度, 从上到下是深度)
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
class Solution {
public:
// 递归左右子树,判断左右子树的高度是否相差为2
int depDiff(TreeNode* root){
if(root == NULL) return 0;
// 后续遍历,分别获取左右子树的深度
int left = depDiff(root->left);
if(left == -1) return -1;
int right = depDiff(root->right);
if(right == -1) return -1;
int diff = abs(left-right);
return diff > 1 ? -1 : max(left, right) + 1;
}
bool isBalanced(TreeNode* root) {
return depDiff(root) == -1 ? false : true;
}
};
2. 二叉树的所有路径 (回溯)
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
- 1.该题的递归终止条件,不是root==NULL, 而是判断当前节点是否为叶子节点
- 2.本题使用回溯的思想,每次递归遍历都需要弹出 上一层左右子树添加到path中的元素
class Solution {
public:
void travel(TreeNode* node, vector<int> &path, vector<string> &result){
path.push_back(node->val);
// 终止条件,遇到叶子节点
if(node->left == NULL && node->right ==NULL){
string sPath;
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 ;
}
// 前序遍历,处理单层逻辑
// 注意每次left和right都需要进行pop
if(node->left){
travel(node->left, path, result);
path.pop_back(); // 回溯将另一个子树遍历的节点弹出
}
if(node->right){
travel(node->right, path, result);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> path;
vector<string> result;
travel(root, path, result);
return result;
}
};
3.左叶子之和
给定二叉树的根节点 root ,返回所有左叶子之和。
- 如何 判断左叶子节点
- 叶子节点不算是 左叶子节点
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root == NULL) return 0;
// 叶子节点不算左叶子
if(root->left == NULL && root->right == NULL) return 0;
// 左
int leftNum = sumOfLeftLeaves(root->left);
// 1.中 判断左叶子
if(root->left!=NULL && root->left->left == NULL && root->left->right==NULL){
leftNum = root->left->val;
}
// 右
int rightNum = sumOfLeftLeaves(root->right);
return leftNum + rightNum;
}
};