110.平衡二叉树
class Solution {
public:
int getHeight(TreeNode* node){
if (node==nullptr) return 0;
int leftCount = getHeight(node->left);
if (leftCount==-1) return -1; //如果有一个子树为非平衡二叉树,所有父树都返回-1
int rightCount = getHeight(node->right);
if (rightCount==-1) return -1;
if (abs(leftCount - rightCount) > 1) return -1; //计算子树深度之差
return max(leftCount, rightCount) + 1; //返回较长的子树作为该节点的深度
}
bool isBalanced(TreeNode* root) {
return getHeight(root)==-1? false:true;
}
};
其实就是一个求最大深度,增加了对于每个节点点左右子树深度的判断。
//求最大深度
class Solution {
public:
int getDepth(TreeNode* node){
if (node==nullptr) return 0;
int leftDepth = getDepth(node->left);
int rightDepth = getDepth(node->right);
int depth = max(leftDepth, rightDepth) + 1; //关键:每一层的递归出口,叶子结点会返回0+1=1
return depth;
}
int maxDepth(TreeNode* root) {
return getDepth(root);
}
};
257. 二叉树的所有路径
回溯法:是一种纯暴力搜索,用于处理组合(无顺序)、切割、子集、排列(有顺序)、棋盘问题。
//回溯算法模板
void backtracking(参数){
if (终止条件){
存放结果;
return ;
}
for (选择:本层集合中元素(树节点孩子的数量就是集合的大小)){
处理节点;
backtracking(路径,选择列表) //递归
回溯,撤销处理结果;
}
}
if (node->left){
traversal(node->left, path, result);//处理当前路径
path.pop_back();//回溯,去查找当前节点的右节点是否有路径
}
if (node->right){
traversal(node->right, path, result);
path.pop_back();
}
对这一步的理解
将1保存到数组后通过
if (node->left){
traversal(node->left, path, result);//处理当前路径
进入2进行处理,2的结果会自动保存到result里,具体是怎么做的在2作为父节点的的递归里会自动实现。我们需要做的是回到当前节点1。
只有回到了1才能对3进行处理。
这道题和回溯的模板对应的可以说是严丝合缝了。
404.左叶子之和
需要在父节点的位置就判断左叶子,因为当前节点无法知道自己是左叶子还是右叶子。
使用后序遍历,因为判断当前节点是不是叶子结点需要在当前节点来判断,判断它是不是左孩子需要其父节点来判断。后序遍历会在确定了一个节点左孩子是不是叶子节点后才处理其父节点,这个顺序比较合适。
class Solution {
public:
int sumLeftLeave(TreeNode* node){
if (node==nullptr) return 0;
if (node->left==nullptr && node->right==nullptr) return 0;
int leftSum=0;
if (node->left){
leftSum = sumLeftLeave(node->left);
}
if (node->left && !node->left->left && !node->left->right){ //如果当前节点有左叶子节点则更新leftSum的值
leftSum = node->left->val;
}
int rightSum=0;
if (node->right){
rightSum = sumLeftLeave(node->right);
}
return leftSum+rightSum;
}
int sumOfLeftLeaves(TreeNode* root) {
return sumLeftLeave(root);
}
};
这也可以套用回溯算法的模板。