今日内容:
- 110.平衡二叉树
- 257. 二叉树的所有路径
- 404.左叶子之和
一、平衡二叉树
本体因为要求是否符合平衡二叉树,平衡二叉树要求高度差不能大于1,所以应用后序遍历的递归。
然后上递归三部曲:
1、确定返回值和函数参数:
由于返回的是二叉树的高度差,所以返回值应为int型数据。递归参数应为树节点。
int getheight(Treenode* node)
2、明确终止条件
当以所遇节点为根节点的树高度为0时说明遇到了空节点,应返回。
if(node ==NULL){
return 0;
}
3、单层逻辑
左子树遍历的值为-1,则整个不符合,右子树遍历值为-1,则整个也不符合。
然后在比较该节点是否二者差的绝对值大于一,若大于1则不符合。
若不大于1则返回最大高度+1;
int leftHeight = getHeight(node->left);
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right);
if (rightHeight == -1) return -1;
return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight)
读完代码后才感受到这题用后序遍历的必要性,能先推到子树然后逐级返回。
有了递归三部曲之后感觉就顺水推舟,但是自己还是没有太好的思路。
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;
return abs(leftheight-rightheight) >1 ? -1:1+max(leftheight,rightheight);
}
bool isBalanced(TreeNode* root) {
return getheight(root)==-1? false:true;
}
};
迭代大致看懂等2刷了。
2、 二叉树的所有路径
这题因为要输出所有的路径,所以需要从叶子节点回溯到前面的节点。
下面就要用递归三部曲。
1、确定参数及返回值
本体输出的时路径不需要返回值,所以类型是void,要输出路径所以参数为节点,路径,和result
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result)
2、找到终止条件
要找叶子节点,所以左右子树都要指向空。
if (cur->left == NULL && cur->right == NULL) { // 遇到叶子节点
string sPath;
for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点)
result.push_back(sPath); // 收集一个路径
return;
}
3、单层递归
if (cur->left) {
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) {
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
4、整体
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& path,vector<string>& result){
path.push_back(cur->val);
if(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;
}
};
整体有待进一步理解。
三、做叶子之和
本来想用层级遍历试试,但确实没法确认是不是左孩子.
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
queue<TreeNode*> que;
if(root==NULL) return 0;
int num=0;
que.push(root);
while(!que.empty()){
int size= que.size();
for(int i=0;i<size;i++){
TreeNode* node = que.front();
que.pop();
if(node->left!=NULL&&node->left->left==NULL&&node->left->right==NULL){
num+=node->left->val;
}
if(node->right) que.push(node->right);
if(node->left) que.push(node->left);
}
}
return num;
}
};
后来看题解恍然大悟。
回溯法:
递归三部曲:1、确定递归函数的参数和返回值
返回数值之和所以为int
2、确定终止条件
if(root==NULL) return 0;
3、确定单层递归的逻辑
int leftValue = sumOfLeftLeaves(root->left); // 左
if (root->left && !root->left->left && !root->left->right) {
leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right); // 右
int sum = leftValue + rightValue; // 中
return sum;
整体:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(root==NULL) return 0;
if(root->left==NULL&&root->right==NULL) return 0;
int leftValue =sumOfLeftLeaves(root->left);
if(root->left&&!root->left->left&&!root->left->right){
leftValue=root->left->val;
}
int rightValue =sumOfLeftLeaves(root->right);
int sum=leftValue+rightValue;
return sum;
}
};
整体难度比较大,花的时间也挺长,理解程度不够。