力扣打卡Day16 二叉树Part03 平衡二叉树+二叉树的所有路径+左叶子之和+完全二叉树的节点个数

110. 平衡二叉树 - 力扣(LeetCode)

平衡树:所有节点的左子树的深度和右子树的深度差值不超过1

我去,竟然差一点就做出来了。

忘记递归判断左子树和右子树是否是平衡的了,,很重要啊。

还是很感动,我离递归做出来最近的一集。

class Solution {
public:
    int getDepth(TreeNode* root) {
        if(root==nullptr) return 0;
        return max(getDepth(root->left),getDepth(root->right))+1;
    }
    bool isBalanced(TreeNode* root) {
        if(root==nullptr) return true;
        int leftDepth=getDepth(root->left);
        int rightDepth=getDepth(root->right);

        if(abs(leftDepth-rightDepth)<=1&&isBalanced(root->left)&&isBalanced(root->right)) {
            return true;
        }
        else return false;
    }
};

257. 二叉树的所有路径 - 力扣(LeetCode)

这题结合了题解和官方题解来抄的。

心得是:在递归过程中很重要一点就是要确定遍历的顺序。

比如在这里采用的是前序遍历,顺序就是:中左右。所以要依次操作。

并且判断叶子节点的方法是左节点和右节点为空,也就是所谓的一个“收获”的季节。

这题好像说是渗透了一点回溯的内容,等我学到那里再看看。

class Solution {
public:
    void getTreePath(TreeNode* node, string path, vector<string>& vec) {
        // 前序遍历
        if(node!=nullptr) {
            // 中
            path+=to_string(node->val);
            if(node->left==nullptr&&node->right==nullptr) {
                vec.push_back(path);
                return;
            }
            else {
                path+="->";
                // 左
                getTreePath(node->left,path,vec);
                // 右
                getTreePath(node->right,path,vec);
            }
        }
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string>ans;
        getTreePath(root,"",ans);
        return ans;
    }
};

 404. 左叶子之和 - 力扣(LeetCode)

抄题解感想:要判断是不是左叶子节点只能通过它的父节点来判断,即父节点的左节点存在,且左节点是叶子节点(左节点的左节点+左节点的右节点 都不存在)。所以实际操作的这一步就直接在父节点里完成了,终止条件那里如果是叶节点直接return 0了。

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        // 只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。 所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,那么终止条件为:
        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; // 真正的操作在这一步就已经全部完成了,所以前面遇到叶子结点直接return 0了
        }
        int rightValue = sumOfLeftLeaves(root->right);  // 右

        int sum = leftValue + rightValue;               // 中
        return sum;
    }
};

吐槽:这题的题号就跟我的脑子一样 

222. 完全二叉树的节点个数 - 力扣(LeetCode)

层序遍历惨遭超出内存限制,为啥题解这样写可以?可能是样例改了

class Solution {
public:
    int countNodes(TreeNode* root) {
        queue<TreeNode*> que;
        int ans=0;
        if(root!=nullptr) que.push(root);

        while(!que.empty()){
            int size=que.size();
            while(size--) {
                TreeNode* node=que.front();
                que.pop();
                ans++;

                if(root->left) que.push(root->left);
                if(root->right) que.push(root->right);
            }
        }
        return ans;
    }
};

迭代法

虽然感觉思路很简单,但还是自己想不出来、得抄别人的思路。

然后我拎出来一个节点和它的子节点,根据图来看了一下,确实是这么一个道理,,

内核就是左右中按顺序遍历。

class Solution {
public:
    int countNodes(TreeNode* root) {
        if(root==nullptr) return 0;

        // if(root->left==nullptr&&root->right==nullptr) return 1;

        return countNodes(root->left)+countNodes(root->right)+1;
    }
};

统计深度和最后一层的节点数

听说java可以用findNode(i)函数来查看最后一层的第i个节点是否为空

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值