题目链接
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。
根节点的高度就是这棵树的最大深度。
求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)
这里看不懂可以看二叉树的最大深度和最小深度。
递归法的单层递归的逻辑:
(1)分别求左子树和右子树高度,计算高度差;
(2)如果高度差大于1,记当前树的高度为-1;否则,当前树的高度是max(左子树高度,右子树高度) + 1;
(3)当然,如果求出的左子树或右子树的高度已经为-1,直接返回-1即可(底层非平衡二叉树,结果会一直传给上层);
(4)最终返回整棵树高度是否为-1的bool值,即是否为平衡二叉树;
class Solution {
public:
int gethight(TreeNode* root){
if(root==nullptr) return 0;
//nt result=-1;
int leftdepth=gethight(root->left);
if(leftdepth==-1) return -1;
int rightdepth=gethight(root->right);
if(rightdepth==-1) return -1;
if(abs(leftdepth-rightdepth)>1) return -1;
//else result=max(leftdepth,rightdepth)+1;
else return 1+max(leftdepth,rightdepth);
}
bool isBalanced(TreeNode* root) {
return gethight(root)==-1?false:true;
}
};
题目链接
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
先使用递归的方式,来做前序遍历。要知道递归和回溯就是一家的,本题也需要回溯。
class Solution {
public:
void getpath(TreeNode* cur,vector<int> &path,vector<string> &spath){
path.push_back(cur->val);
if(cur->left){
getpath(cur->left,path,spath);
path.pop_back();
}
if(cur->right){//可以控制空节点不入循环
getpath(cur->right,path,spath);
//递归完,要做回溯,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点。
//回溯和递归是一一对应的,有一个递归,就要有一个回溯,所以回溯要和递归永远在一起,
path.pop_back();
}
if(cur->left==nullptr&&cur->right==nullptr){// 左右孩子都为空,遇到叶子节点
string str;
for(int i=0;i<path.size()-1;i++){// 将path里记录的路径转为string格式
str+=to_string(path[i]);
str+="->";
}
str+=to_string(path[path.size()-1]);// 记录最后一个节点(叶子节点)
spath.push_back(str);
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int> path;
vector<string> spath;
if(root==nullptr) return spath;
getpath(root,path,spath);
return spath;
}
};
如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子。
因为要通过递归函数的返回值来累加求取左叶子数值之和,所以用后序遍历。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL) return 0;
int leftValue = sumOfLeftLeaves(root->left); // 左
int rightValue = sumOfLeftLeaves(root->right); // 右
if (root->left && !root->left->left && !root->left->right) { // 左子树就是一个左叶子的情况
leftValue = root->left->val;
}
int sum = leftValue + rightValue; // 中
return sum;
}
};
迭代法使用前中后序都是可以的,只要把所有节点都遍历到,把左叶子节点统计出来
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> st;
if(root==nullptr) return 0;
st.push(root);
int result;
while(!st.empty()){
TreeNode* cur=st.top();
st.pop();
if(cur->left) st.push(cur->left);
if(cur->right) st.push(cur->right);
if(cur->left&&!cur->left->left&&!cur->left->right){
result+=cur->left->val;
}
}
return result;
}
};