1.平衡二叉树
思路:
1.平衡二叉树:它具有一个左子树和一个左子树,且对于任意一个子树而言,左子树和右子树高度差不超过1。
2.求高度,所以用后序遍历,左右中。
class Solution {
public:
int getHeight(TreeNode* node){
if(node == NULL) return 0;
//求高度,后序
int leftHeight = getHeight(node -> left);
if(leftHeight == -1) return -1;
int rightHeight = getHeight(node -> right);
if(rightHeight == -1) return -1;
if(abs(leftHeight - rightHeight) > 1) return -1;
else{
return 1 + max(leftHeight,rightHeight);
}
}
bool isBalanced(TreeNode* root) {
int result = getHeight(root);
if(result == -1) return false;
else{
return true;
}
}
};
2.二叉树的所有路径
思路:
1.这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
2.前序遍历:只有前序遍历才能让父节点去指向它的孩子结点,找到对应的路径。
3.在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
4.因为是所有路径,所以找到一条路径后,需要返回到起点,然后继续找其他路径。所以必然会涉及到回溯操作。
class Solution {
public:
void traversal(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 ;
}
if(node -> left){
traversal(node -> left,path,result);
path.pop_back(); //回溯
}
if(node -> right){
traversal(node -> right,path,result);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if(root == NULL) return root;
traversal(root,path,result);
return result;
}
};
4. 回溯和递归是一一对应的,有一个递归,就要有一个回溯。
5.中的代码一定要写在终止条件之前。因为终止条件只需要判断到叶子结点即可,如果中的代码放在终止条件之后的话,中的代码如果是叶子结点的话,其代码还没有执行,就return了,就会把叶子结点落下。所以,一定要把中结点放在终止条件之前,把叶子结点加进去。
6.开始没有判断node == NULL ,但是后面的逻辑可以控制空节点不入循环。所以递归前要加上判断语句,下面要递归的节点是否为空。if(node->left == NULL)
7.重点关注!!! 函数的参数是vector<int>& path,如果使用string path也可以,但是使用string& path就不可以了。这里涉及到C++的知识,参数的传递。
3.左叶子之和
思路:
1.左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点。
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);
if(root -> left != NULL && root -> left -> left == NULL && root -> left -> right ==NULL)
leftnum = root -> left -> val;
int rightnum = sumOfLeftLeaves(root -> right);
int sum = leftnum + rightnum;
return sum;
}
};
这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。
此时就要通过节点的父节点来判断其左孩子是不是左叶子了。
平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。