110.平衡二叉树
题目链接:110. 平衡二叉树 - 力扣(LeetCode)
题目描述:
解题思路:采用递归的思路去判断每一个子树是否是平衡二叉树,若有一个子树不是平衡二叉树则整个二叉树都不是平衡二叉树,所以采用后序遍历,让父节点收集左右孩子的信息,若其中有一个不是平衡二叉树,则直接返回给父节点-1。
1、终止条件if(node == NULL)return 0;
2、函数返回值类型和变量,返回值是int类型,记录二叉树的高度,变量即传入的节点。
3、单层递归逻辑,判断左右孩子是否有返回值为-1的,若有则直接给父节点返回-1,若没有则判断左右子树的高度差绝对值是否大于1,大于1 的情况则直接返回-1,不大于的情况下则返回左右子树中最高的高度值+1。
代码实现:
class Solution {
public:
int getheight(TreeNode *node){
if(node == NULL) return 0;
int left_height = getheight(node->left);
int right_height = getheight(node->right);
if(left_height == -1) return -1;
if(right_height == -1) return -1;
int result;
if(abs(left_height - right_height)>1) return -1;
else {
result = 1 +max(left_height,right_height);
}
return result;
}
bool isBalanced(TreeNode* root) {
int height;
height = getheight(root);
if(height == -1)return false;
else return true;
}
};
257.二叉树所有路径
题目链接:257. 二叉树的所有路径 - 力扣(LeetCode)
题目描述:
解题思路:这题要求所有的路径,即这题需要将遍历到的元素挨个弹出,才能收集到不同的路径 即回溯的思想。采用一个path来记录路径,一个result来存储结果,当遍历到下一个节点的时候则保存进path中,当达到了遍历终止的条件的时候,即到达叶子节点,即返回path中所存储的路径,然后使用pop将已经收集到的路径节点弹出,继续收集新的路径。
代码实现:
class Solution {
public:
void traversal(TreeNode *cur ,vector<int>&path,vector<string>&result){
path.push_back(cur->val);
if(cur != NULL && cur->left == NULL && cur->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;
}
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 == NULL)return result;
traversal(root,path,result);
return result;
}
};
下图画出了代码执行的流程,使用红色荧光笔画出来的地方是达到了终止条件收集路径之后进行return结束这一层代码执行的过程,然后进行pop回溯,而绿色和蓝色荧光笔所花的框是函数完全执行完之后自动返回到上一层的情况,使用pop进行回溯。
404.左叶子之和
题目链接:404. 左叶子之和 - 力扣(LeetCode)
题目描述:
解题思路:仍然采用递归的思想,挨个判断每个子树的左叶子的和,然后返回给父节点,最后返回到根节点。
1、函数返回值类型为int,用来返回左叶子的和,传入参数即节点。
2、终止条件,当遍历到左叶子的父节点的时候即需要收集左右子树的左叶子之和,因为叶子节点的判断条件是自身不为空,但是左右子树为空。若使用当前节点进行判断的话, 则无法判断出这个节点是左叶子还是右叶子,所以需要用父节点进行判断,即父节点的左孩子不为空,左孩子的左孩子为空,左孩子的右孩子为空,即为左叶子节点,然后进行搜集信息。
3、单层递归逻辑,根节点收集左右子树的左叶子节点进行求和即可。
代码实现:
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);
int rightnum = sumOfLeftLeaves(root->right);
if(root->left!=NULL && root->left->left==NULL && root->left->right==NULL){
leftnum = root->left->val;
}
int sum = leftnum + rightnum;
return sum;
}
};
(ps:第一次遇到回溯,把整个思路和过程想明白花了一些时间)