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

题目链接:leetcode 104.二叉树的最大深度

文章讲解:代码随想录 104.二叉树的最大深度讲解

视频讲解:二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | 104.二叉树的最大深度

思路和解法

题目:
给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
想法:
今天的题目在学层序遍历的时候都做过。
方案一:层序遍历,每遍历到新一层的时候,记录深度+1即可。
方案二:递归法,递归获取子树的深度,要注意边界条件的设置,是遍历到空指针返回深度0,然后因为要取最大深度,所以取左右子树中更深的一个,再加上本节点的一层,然后返回结果。

/**
 * 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) {
        //使用队列
        queue<TreeNode*> que;
        //初始化
        if (root != nullptr) {
            que.push(root);
        }
        //记录深度
        int depth = 0;
        //开始遍历 while中每次是一层
        while (!que.empty()) {
            depth++;
            //一定要提前取出元素个数
            int size = que.size();
            //每层循环是当前层中的一个元素
            for (int i = 0; i < size; i++) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur -> left) que.push(cur -> left);
                if (cur -> right) que.push(cur -> right);
            }
        }
        return depth;  
    }
};

class Solution {
public:
    int getDepth(TreeNode* node) {
        if (node == nullptr) return 0;
        int leftDepth = getDepth(node -> left);
        int rightDepth = getDepth(node -> right);
        int depth = max(leftDepth, rightDepth) + 1;
        return depth;
    }
    int maxDepth(TreeNode* root) {
        //使用递归法
        int result = getDepth(root);
        return result;
    }
};

题目链接:leetcode 111.二叉树的最小深度

文章讲解:代码随想录 111.二叉树的最小深度讲解

视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度

思路和解法

题目:
给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。
想法:
方案一:层序遍历迭代法,因为要取最小深度,所以在层序遍历过程中,遇到第一个叶子节点返回深度即可。
方案二:递归法,要注意的点比较多,虽然是取最小深度,但是必须是到叶子节点的深度,因此只要当前节点有子节点,就要递归获取,如果有两个子节点,就递归获取到叶子节点深度更小的深度。

/**
 * 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) {
        //使用队列
        queue<TreeNode*> que;
        //初始化
        if (root != nullptr) {
            que.push(root);
        }
        //记录深度
        int depth = 0;
        //开始遍历 while中每次是一层
        while (!que.empty()) {
            depth++;
            //一定要提前取出元素个数
            int size = que.size();
            //每层循环是当前层中的一个元素
            for (int i = 0; i < size; i++) {
                TreeNode* cur = que.front();
                que.pop();
                if (cur -> left) que.push(cur -> left);
                if (cur -> right) que.push(cur -> right);
                if (!cur -> left && !cur -> right) {
                    return depth;
                }
            }
        }
        return depth;  
    }
};

//递归法 后序遍历更容易理解
class Solution {
public:
    //递归函数
    int getDepth(TreeNode* node) {
        //终止条件
        if (node == nullptr) {
            return 0;
        }
        //记录深度
        int depth = 0;
        //如果仅有一个子节点,最小深度还需要向下递归
        if (node -> left && !node -> right) {
            //向左子节点向下递归
            depth = getDepth(node -> left) + 1;
        } else if (!node -> left && node -> right) {
            //向右子节点向下递归
            depth = getDepth(node -> right) + 1;
        } else {
            //左右子节点都有,取更小的深度
            depth = min(getDepth(node -> left), getDepth(node -> right)) + 1;
        }
        return depth;
    }

    int minDepth(TreeNode* root) {
        return getDepth(root);
    }
};

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

文章讲解:代码随想录 222.完全二叉树的节点个数讲解

视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量

思路和解法

题目:
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
想法:
获取节点个数层序遍历可以实现,但是时间复杂度不够好,利用完全二叉树的性质可以更快。这也是本题的考察目的。
完全二叉树的性质:
1、一直向左深入和一直向右深入,两边深度一致的树是满二叉树,完全二叉树向下递归一定会出现满二叉树,最坏的情况就是到叶子节点,也算满二叉树。
2、如果完全二叉树为h层,第h层包含 2 h − 1 2^{h-1} 2h1个节点,整棵树包含 2 h − 1 2^{h}-1 2h1个节点。

/**
 * 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 == nullptr) return 0;
        //利用完全二叉树性质
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
        while (left) {  // 求左子树深度
            left = left->left;
            leftDepth++;
        }
        while (right) { // 求右子树深度
            right = right->right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
        }
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};
  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值