代码随想录算法训练营第十六天 | 104. 二叉树的最大深度、111. 二叉树的最小深度

104. 二叉树的最大深度

视频讲解

主要思路:

(1)因为要求的最大深度其实就是高度,所以采用后序遍历,(一般来说,求高度都用后序遍历,求深度都用前序遍历)

(2)递归三步:

1. 参数:节点;返回值:该节点深度

2. 结束条件:节点为空

3. 递归逻辑:后序遍历

”左右“:都是递归调用

“中”:是处理逻辑

易错点

(1)为什么用后序遍历可以实现从叶子结点往中间节点:视频讲解

代码实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root == NULL) return 0;
        int leftHight = maxDepth(root -> left);
        int rightHight = maxDepth(root -> right);
        int ans = max(leftHight, rightHight) + 1;
        return ans;
    }
};

111. 二叉树的最小深度

视频讲解

主要思路:

(1)首先看清题目要求,求的是根节点到最小叶子结点的距离

(2)依然采用后序遍历,通过将孩子情况返回给父节点,因为高度从1开始,所以父节点+1

易错点:

(1)递归结束为什么返回0:

因为此时已遍历到叶子节点,高度是1,再往下的NULL节点高度是0

(2)“中”的处理逻辑:

不能贸然取两个子树中高度较小的一个,因为如果有一个子树为空,那么所谓"最小值"并没有从叶子节点开始计算

代码实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root == NULL) return 0;

        int leftHeight = minDepth(root -> left);
        int rightHeight = minDepth(root -> right);
        int minHeight;
        if(root -> left == NULL && root -> right != NULL) minHeight = rightHeight + 1;
        else if(root -> left != NULL && root -> right == NULL) minHeight = leftHeight + 1;
        else minHeight = min(leftHeight, rightHeight) + 1;
        return minHeight;
    }
};

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

视频讲解

手撕+模拟

主要思路:

通过后序遍历一棵一棵找到满二叉树后加上去

易错点:

(1)递归结束条件:

1. 遍历到叶子结点

2.子树是满二叉树:

[1] 判断方法:向左遍历深度等于向右遍历深度

如果发现“大”的左右子树不是满二叉树,就按左右中递归,即以当前子树左孩子为根节点,直到找到一个满二叉树为止或叶子结点

代码实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        //递归结束条件
        if(root == NULL) return 0;
        TreeNode* leftNode = root -> left;
        TreeNode* rightNode = root -> right;
        int leftDepth = 0;
        int rightDepth = 0;
        while(leftNode) {
            leftNode = leftNode -> left;
            leftDepth++;
        }
        while(rightNode) {
            rightNode = rightNode -> right;
            rightDepth++;
        }
        //求出当前满二叉树的节点总数
        if(leftDepth == rightDepth) return (2 << leftDepth) - 1;
        
        //后序遍历里"左右"递归调用
        int leftSubtree = countNodes(root -> left);
        int rightSubtree = countNodes(root -> right);
        //后序遍历里"中"处理,左右满二叉树节点相加再加当前根节点
        return leftSubtree + rightSubtree + 1;
    }
};

第一次写错误 

(1)对于while里是leftNode还是leftNode -> left其实也关系到leftDepth为什么赋值是0,如果while里是leftNode -> left,则有可能leftNode已经是空节点了,那就操作空指针了,所以while里是leftNode,对应leftDepth也应该赋为0,以叶子结点为例,能进入循环,leftDepth变为1后退出循环,正好是层数

你可能感兴趣的:(算法训练营,算法,leetcode,数据结构)