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

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

2023年3月16日 第三十天补

104. 二叉树的最大深度

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

思路:

  • 该题目比较简单,我这里用递归和迭代分别实现,思路会在代码里面加注释

递归实现

时间复杂度:O(n),空间复杂度O(n)

代码:


class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==nullptr)return 0;
        else
        {
            // 根树的深度就是左右子树最大深度+1
            return std::max(maxDepth(root->left),maxDepth(root->right))+1;
        }
    }
};

迭代实现

时间复杂度:O(n),空间复杂度O(n)

代码:

class Solution {
public:
    // 层序遍历,每到一个新层,高度+1
    int maxDepth(TreeNode* root) {
        int depth = 0;
        std::queue<TreeNode*> stk;
        int cur_size = 0;
        int next_size = 0;
        if(root!=nullptr)
        {
            stk.push(root);
            ++cur_size;
        }
        while(!stk.empty())
        {
            auto node = stk.front();
            if(node->left!=nullptr)
            {
                stk.push(node->left);
                ++next_size;
            }
            if(node->right!=nullptr)
            {
                stk.push(node->right);
                ++next_size;
            }
            --cur_size;
            stk.pop();
            if(cur_size==0)
            {
                ++depth;
                cur_size= next_size;
                next_size = 0;
            }
        }
        return depth;
    }
};

总结:

  • 难度不大,不过这种题目思路一定要清楚些
  • 做题体验:哈哈哈哈 > 嘿嘿 > 哎哎 > 嘤嘤
  • 时间:未计
  • 一刷

111. 二叉树的最小深度

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

思路:

  • 这题相对求最大深度稍有不同,不过也比较简单
  • 我还是用递归和迭代分别实现,然后在代码里注释解释

时间复杂度:O(n),空间复杂度O(n)

递归法

代码:

class Solution
{
public:
    int minDepth(TreeNode *root)
    {
        // 如果一个节点的左右子树都不为空,则取两子树深度的最小值+1即可
        // 如果其中一个是空子树,则取另一个子树的深度+1
        if(root==nullptr) return 0;
        if(root->left == nullptr &&root->right ==nullptr)return 1;
        else if(root->left == nullptr) return minDepth(root->right) +1;
        else if(root->right == nullptr) return minDepth(root->left) +1;
        else return std::min(minDepth(root->left),minDepth(root->right)) + 1;
    }
};

迭代法

代码:

// 层序遍历,遇到第一个叶子节点,就返回当前的深度
class Solution
{
public:
    int minDepth(TreeNode *root)
    {
        int depth = 0;
        std::queue<TreeNode *> stk;
        int cur_size = 0;
        int next_size = 0;
        if (root != nullptr)
        {
            stk.push(root);
            ++cur_size;
        }
        while (!stk.empty())
        {
            auto node = stk.front();
            if (node->left == nullptr && node->right == nullptr)
            {
                return depth + 1;
            }
            if (node->left != nullptr)
            {
                stk.push(node->left);
                ++next_size;
            }
            if (node->right != nullptr)
            {
                stk.push(node->right);
                ++next_size;
            }
            --cur_size;
            stk.pop();
            if(cur_size==0)
            {
                cur_size = next_size;
                next_size = 0;
                ++depth;
            }
        }
        return depth;
    }
};

总结:

  • 难度不大,不过这种题目思路一定要清楚些
  • 做题体验:哈哈哈哈 > 嘿嘿 > 哎哎 > 嘤嘤
  • 时间:未计
  • 一刷

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

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

思路:

  • 满二叉树是叶子节点全部在同一层的树
  • 而完全二叉树指最下层节点全部都左连续,完全二叉树包含满二叉树
  • 这道题我写三个解法
  • 第一个解法是对数递归求节点个数,这种方式对任何的二叉树都适用
  • 第二个解法是针对完全二叉树特性,实现一种遍历更少节点的求法,具体思路在解法里再讲
  • 第三个解法是迭代法,同样也是对任何二叉树适用

时间复杂度:O(n),空间复杂度O(n)

通用递归

代码:

class Solution
{
public:
    int countNodes(TreeNode *root)
    {
        if (root == nullptr)
            return 0;
        else
            // 将左子树的节点个数和右子树节点个数想加再加上当前节点
            return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

完全二叉树递归

思路:

  • 完全二叉树可以分成若干个深度不等的满二叉树
  • 对满二叉树的节点个数求值就可以使用数学公式

代码:

class Solution
{
public:
    int countNodes(TreeNode *root)
    {
        if(root == nullptr)return 0;
        // 获取当前节点左右树边的长度,如果相等,那这一部分肯定是满二叉树
        int leftDepth = getLeftDepth(root);
        int rightDepth = getRightDepth(root);
        if (leftDepth == rightDepth)
        {
            // 是用满二叉树求值公式
            return getManTreeNodeCount(leftDepth);
        }
        else
        {
            // 递归判断左右子树是不是满二叉树
            return countNodes(root->left) + countNodes(root->right) + 1;
        }
    }

    // 左边深度
    int getLeftDepth(TreeNode *node)
    {
        if (node == nullptr)
            return 0;
        else
            return getLeftDepth(node->left) + 1;
    }

    // 右边深度
    int getRightDepth(TreeNode *node)
    {
        if (node == nullptr)
            return 0;
        else
            return getRightDepth(node->right) + 1;
    }

    int getManTreeNodeCount(int depth)
    {
        return chengfang(depth) - 1;
    }

    int chengfang(int mi)
    {
        int result = 1;
        while (mi--)
        {
            result *= 2;
        }
        return result;
    }
};

通用迭代

代码:

// 层序遍历累加求值
class Solution
{
public:
    int countNodes(TreeNode *root)
    {
        std::queue<TreeNode *> nodeQue;
        if (root != nullptr)
        {
            nodeQue.push(root);
            ++count;
        }
        while (!nodeQue.empty())
        {
            auto node = nodeQue.front();
            nodeQue.pop();
            if (node->left != nullptr)
            {
                nodeQue.push(node->left);
                ++count;
            }
            if (node->right != nullptr)
            {
                nodeQue.push(node->right);
                ++count;
            }
        }
        return count;
    }
    int count = 0;
};

总结:
*

  • 做题体验:哈哈哈哈 > 嘿嘿 > 哎哎 > 嘤嘤
  • 时间:未计
  • 一刷
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值