先来看第一题
110.平衡二叉树:代码随想录
这个题目是让我们判断一个树是否为一棵平衡二叉树,首先平衡二叉树的定义就是左右子树的高度差的绝对值不大于1,所以这里为我们就要递归遍历每一个结点,去计算他的左右节点的高度差,然后在返回是否为一棵平衡二叉树,下面来看具体代码的实现
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(root==NULL) return true;
if(isTree(root->left,root->right)==false){
return false;
}
return isBalanced(root->left) && isBalanced(root->right);
}
bool isTree(TreeNode* left, TreeNode* right){
//if(left==NULL && right==NULL) return true;
// else if(left!=NULL || right!=NULL) return true;
int leftdepth=depth(left);
int rightdepth=depth(right);
if(fabs(rightdepth-leftdepth)>1) return false;
return true;
}
int depth(TreeNode* root){
if(root==NULL) return 0;
int leftdepth=depth(root->left);
int rightdepth=depth(root->right);
return max(leftdepth,rightdepth)+1;
}
};
我这里写了三个函数,分别是主函数,和求深度的函数,和判断是否为平衡二叉树的函数,求深度的函数不用多说,主要来看第二个,这里传参数,传的是一个结点的左右子树,有人可能会好奇,为什么这里没有判断他的左右子树是否为空,因为我这里要求他的深度,而求他深度的函数里,就右判断他为空时,返回的深度是0,然后在做差返回即可,来看主函数的部分,主函数一开始先判断根节点,在递归判断他的左节点和右节点
257. 二叉树的所有路径:代码随想录
这道题就是让你将从根节点到所有叶子结点的路径做一个打印输出,这里要特别注意回溯的思路,因为这里用的是地址传递,所以每一次递归他的参数都会发生改变,来看具体的代码
class Solution {
public:
void Traverse(TreeNode* root, vector<int> &vec, vector<string> &result){
vec.push_back(root->val);
if(root->left==NULL && root->right==NULL){
string path;
for(int i=0;i<vec.size()-1;i++){
string s="";
stringstream ss;
ss<<vec[i];
ss>>s;
path+=s;
path+="->";
}
string s="";
stringstream ss;
ss<<vec[vec.size()-1];
ss>>s;
path+=s;
result.push_back(path);
return ;
}
if(root->left!=NULL){
Traverse(root->left,vec,result);
vec.pop_back();
}
if(root->right!=NULL){
Traverse(root->right,vec,result);
vec.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> vec;
vector<string> result;
if(root==NULL) return result;
Traverse(root,vec,result);
return result;
}
};
这里对从int转化为string的处理不做过多的解释,,因为采用的是中序遍历的思想,所以一开始就将值加入到路径数组中,然后如果到叶子节点了,那么就代表我们该将路径储存到结果数组里了,这一步就不做过多的解释了,,然后就是递归遍历左子树和右子树,这里需要判断它是否为空结点记住每一次递归调用结束后都要回溯,这里为什么要回溯,大家可以自己举一个简单的例子,当我这个函数出来之后,必定代表我遇到了叶子节点,所以要将叶子节点弹出,回到叶子结点的上一个结点,然后继续向右遍历,一直循环往复,但是如果这里没有用地址传递,就不用回溯,为什么呢,因为如果是值传递的话,是不会改变他在当前层函数的值的,所以无需回溯
404.左叶子之和:代码随想录
这题我一开始犯了一个很大的错误,我理解错了题目的意思,我以为是求左边结点的和,但其实这道题的意思是求所有为父亲结点的左孩子并且为叶子节点的和,那么直接来看代码
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==NULL) return 0;
if(root->left==NULL && root->right==NULL){
return 0;
}
int leftsum=sumOfLeftLeaves(root->left);
int rightsum=sumOfLeftLeaves(root->right);
int sum=0;
if(root->left!=NULL && root->left->left==NULL && root->left->right==NULL){
sum+=root->left->val;
}
return sum+leftsum+rightsum;
}
};
首先还是一样,当root为空时返回0,因为我们要判断他是不是左孩子,所以这里我们要在他的上一层就做出判断,在叶子节点那一层就直接返回就可以了,所以后面当为叶子节点时,就直接返回0,然后就是后续遍历返回左右和当前的值的和就可
这就是今天的全部内容了,继续加油吧!