day17.|二叉树04

1.平衡二叉树

. - 力扣(LeetCode)

思路:

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.二叉树的所有路径 

. - 力扣(LeetCode)

思路:

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.左叶子之和

. - 力扣(LeetCode)

思路:

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;
    }
};

这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。

此时就要通过节点的父节点来判断其左孩子是不是左叶子了。

平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值