代码随想录算法训练营Day16

本文介绍了如何计算二叉树和N叉树的最大深度、最小深度,以及完全二叉树的节点个数。提供了递归和迭代两种方法,涉及后序遍历和层序遍历策略。同时给出了力扣相关例题,包括104.二叉树的最大深度、559.N叉树的最大深度、111.二叉树的最小深度和222.完全二叉树的节点个数的解题思路和代码实现。
摘要由CSDN通过智能技术生成

Day 16 最大\小深度、完全二叉树节点个数

力扣相关例题

104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
在这里插入图片描述
返回它的最大深度 3 。

后序递归

class Solution {
public:
    //后序遍历
    //二叉树的最大深度就是根节点的最大高度
    int treeheight(TreeNode* node) {
       if (node == NULL) {
           return 0;
       } 
       int lefttree = treeheight(node->left);
       int righttree = treeheight(node->right);
       int height = 1 + max(lefttree, righttree);
       return height;
    }
    int maxDepth(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        int height = treeheight(root);
        return height;
    }

迭代法

class Solution {
public:
    //后序遍历
    //二叉树的最大深度就是根节点的最大高度
    int maxDepth(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        queue<TreeNode*> que;
        que.push(root);
        int maxheight = 0;
        while (!que.empty()) {
            int size = que.size();
            maxheight++;
            //遍历完一层上的所有结点才可以往下一层
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left != NULL) {
                    que.push(node->left);
                }
                if (node->right != NULL) {
                    que.push(node->right);
                }
            }
        }
        return maxheight;
    }
};

559. N 叉树的最大深度

给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

示例 :
在这里插入图片描述
输入:root = [1,null,3,2,4,null,5,6]
输出:3

递归

class Solution {
public:
    int maxDepth(Node* root) {
        if (root == NULL) {
            return 0;
        }
        int maxheight = 0;
        for (int i = 0; i < root->children.size(); i++) {
            maxheight = max(maxheight, maxDepth(root->children[i]));
        }
        //因为计算的是左右孩子的最大深度,返回头节点要+1
        return maxheight + 1;
    }
};

迭代

特别要注意怎么遍历n叉树

class Solution {
public:
    int maxDepth(Node* root) {
        if (root == NULL) {
            return 0;
        }
        queue<Node*> que;
        que.push(root);
        int maxheight = 0;
        while (!que.empty()) {
            int size = que.size();
            maxheight++;
            for (int i = 0; i < size; i++) {
                Node* node = que.front();
                que.pop();
                //这里要特别注意,与二叉树遍历不同但相像
                for (int j = 0; j < node->children.size(); j++) {
                    que.push(node->children[j]);
                }
            }
        }
        return maxheight;
    }
};

111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

示例 :
在这里插入图片描述
输入:root = [3,9,20,null,null,15,7]
输出:2

递归

class Solution {
public:
    int minDepth(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        int lefttree = minDepth(root->left);
        int righttree = minDepth(root->right);
        //若左孩子为空,右孩子不为空,则不是叶子结点,需返回右孩子的叶子结点最小深度
        if (root->left == NULL && root->right != NULL) {
            return righttree + 1;
        }else if (root->left != NULL && root->right == NULL) {//同理
            return lefttree + 1;
        }
        //若两个孩子都为空,则返回
        return 1 + min(lefttree, righttree);
    }
};

迭代

class Solution {
public:
    int minDepth(TreeNode* root) {
       if (root == NULL) {
           return 0;
       }
        int mintreedep = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            mintreedep++; // 记录最小深度
            for (int i = 0; i < size; i++) {
                TreeNode* node = que.front();
                que.pop();
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
                // 当左右孩子都为空的时候,说明是最低点的一层了,退出
                if (node->left == NULL && node->right == NULL) { 
                    return mintreedep;
                }
            }
        }
        return mintreedep;
    }
};
class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        int leftheight = 0; 
        int rightheight = 0; 
        //左子树深度
        while (left) {
            left = left->left;
            leftheight++;
        }
        //右子树深度
        while (right) {
            right = right->right;
            rightheight++;
        }
        if (leftheight == rightheight) {
            return (2 << leftheight) - 1;   //对一个数左移1位就是乘以2,左移n位就是乘以2的n次方
        }
        int lefttree = countNodes(root->left);
        int righttree = countNodes(root->right);
        return lefttree + righttree + 1;
    }
};

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

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

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例 :
在这里插入图片描述
输入:root = [1,2,3,4,5,6]
输出:6

class Solution {
public:
    int countNodes(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        // 开始根据左深度和右深度是否相同来判断该子树是不是满二叉树
        TreeNode* left = root->left;
        TreeNode* right = root->right;
        // 这里初始为0是有目的的,为了下面求指数方便
        int leftheight = 0; 
        int rightheight = 0; 
        //左子树深度
        while (left) {
            left = left->left;
            leftheight++;
        }
        //右子树深度
        while (right) {
            right = right->right;
            rightheight++;
        }
        if (leftheight == rightheight) {
            return (2 << leftheight) - 1;   //对一个数左移1位就是乘以2,左移n位就是乘以2的n次方
        }
        int lefttree = countNodes(root->left);
        int righttree = countNodes(root->right);
        return lefttree + righttree + 1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值