代码随想录算法训练营第15天| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和、 222.完全二叉树的节点个数

110.平衡二叉树

题目链接:110.平衡二叉树

思想:一个树想要是平衡二叉树,首先前提是他的子树是平衡二叉树,所有用从下往上遍历的方法,不断比较左右孩子的深度,就可以判断是不是平衡二叉树了。

class Solution {
public:
    bool isBalanced(TreeNode* root) {
        //从底往上遍历看左右子树深度之差
        //一棵树是平衡二叉树首先他的子树必须是平衡二叉树
        if(root==nullptr) return true;
        if(!isBalanced(root->left)||!isBalanced(root->right)) return false;
        
        if(abs(getdep(root->left)-getdep(root->right))<=1) return true;
        else return false;
    }
    int getdep(TreeNode* root){
        if(root==nullptr) return 0;
        return 1+max(getdep(root->right),getdep(root->left));
    }
};

257. 二叉树的所有路径

题目链接:257. 二叉树的所有路径

思想:在这个题目中我使用了简单的前序遍历解决。在这一题初步了解到回溯的思想,首先我们可以把一个节点的值加入数组中,当当前遍历结束后,再把这个节点中的元素pop出来,一直pop到有未访问的路径为止,使用这种明显含有回溯思想的方法需要拷贝参数地址进行修改。在这里我用的是字符串。

class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> ans;
        string s = "";
        visit(root, s, ans);
        return ans;
    }

    // 先序遍历
    void visit(TreeNode* root, string s, vector<string>& ans) {
        if (root != nullptr) {
            if (root->right == nullptr && root->left == nullptr) {
                s += to_string(root->val);
                ans.push_back(s);
            } else {
                s += to_string(root->val);
                s += "->";
            }
            visit(root->left, s, ans);
            visit(root->right, s, ans);
        }
    }
};

404.左叶子之和

题目链接:404.左叶子之和

思路:首先看当前节点有没有左孩子,如果有的话,则看左孩子的左右孩子是否为空,如果为空,则说明这个节点是左叶子节点。递归遍历整个二叉树,将所有左叶子节点之和相加即可。

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        int sum=0;
        visit(root,sum);
        return sum;
    }
    void visit(TreeNode* root,int &sum){
        if(root==nullptr) return;
        //检测这个的左孩子是否存在 若存在 是否是叶子节点
        if(root->left!=nullptr){
            if(root->left->left==nullptr&&root->left->right==nullptr) sum+=root->left->val;
        }
        visit(root->left,sum);
        visit(root->right,sum);
    }
};

222.完全二叉树的节点个数

题目链接:222.完全二叉树的节点个数

思路:相比于普通二叉树,完全二叉树统计节点个数时可以减少时间复杂度。假如说对于有一个根节点,分别看他左子树最左边的深度和右子树最右边的深度是否相等,就可以判断这棵树是不是完全二叉树。如果是,则可以通过位运算得出节点个数。如果不是,则利用后序遍历来查看他的左右子树是否为完全二叉树,最后左右子树的节点个数相加,得出总结点数,本题不难。

class Solution {
public:
    int countNodes(TreeNode* root) {
        //先看这个这个节点为根节点的树是不是满二叉树
        if(root==nullptr) return 0;
        //满二叉树:左侧右侧深度相同
        int left_dep=0, right_dep=0;
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        while(left!=nullptr){
            left=left->left;
            left_dep++;
        }
        while(right!=nullptr){
            right=right->right;
            right_dep++;
        }
        if(right_dep==left_dep) return (2<<right_dep)-1;//位运算
        int a =countNodes(root->left);
        int b =countNodes(root->right);
        return a+b+1;
    }
};

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值