首页 > 其他分享 >(16/60)二叉树最大深度、最小深度、完全二叉树结点个数

(16/60)二叉树最大深度、最小深度、完全二叉树结点个数

时间:2024-02-08 23:22:05浏览次数:30  
标签:node right TreeNode val 16 int 二叉树 深度 left

终于熬到了春节假~~有些手感了

深度与高度

深度是从根结点到叶结点的距离;高度是从叶结点到根结点的距离。

深度从上往下(根为1);高度从下往上(叶为1)

二叉树最大深度

leetcode:104. 二叉树的最大深度

后序递归法

思路

复杂度分析

时间复杂度:O(N)。遍历了一遍。

空间复杂度:和层数有关。平衡时O(logN),不平衡时O(N)。

注意点

代码实现

/**
 * 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 getMaxDepth(TreeNode* node){
        if(node == NULL) return 0;
        int LMD = getMaxDepth(node->left);
        int RMD = getMaxDepth(node->right);

        return 1 + (LMD > RMD ? LMD : RMD);
    }

    int maxDepth(TreeNode* root) {
        return getMaxDepth(root);
    }
};

N叉树最大深度

leetcode:559. N 叉树的最大深度

后序递归法

思路

还是后序遍历,只不过左右节点处理变为了对子节点数组children处理。

复杂度分析

时间复杂度:O(N)。遍历。

空间复杂度:递归遍历相通:平衡时O(logN),不平衡时O(N)。

注意点

代码实现

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    int getMaxDepth(Node* node){
        if(node == NULL) return 0;
        int maxDepth = 0;
        // 对于每一个child递归
        for(int i = 0;i < node->children.size();i++){
            int temp = getMaxDepth(node->children[i]);
            maxDepth = temp > maxDepth ? temp : maxDepth;
        }

        return maxDepth + 1; 
    }
    int maxDepth(Node* root) {
        return getMaxDepth(root);
    }
};

二叉树最小深度

后序递归法

思路

复杂度分析

注意点

  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 getMinDepth(TreeNode* node){
        if(node == NULL) return 0;
        int LMD = getMinDepth(node->left);
        int RMD = getMinDepth(node->right);
        if(node->left == NULL && node->right != NULL){
            return 1 + RMD;
        }
        if(node->left != NULL && node->right == NULL){
            return 1 + LMD;
        }

        return 1 + ( LMD < RMD ? LMD : RMD );
    }

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

完全二叉树的节点个数

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

后序递归法

思路

节点遍历一遍,后序遍历。

复杂度分析

时间复杂度:O(N)

空间复杂度:最不平衡时O(N),平衡时O(logN)。

注意点

代码实现

/**
 * 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 preTraverse(TreeNode* node){
        if(node == NULL) return 0;
        // 先分支
        int lcount = preTraverse(node->left);
        int rcount = preTraverse(node->right);
		// 再中间
        return lcount + rcount + 1;
    }

    int countNodes(TreeNode* root) {
        return preTraverse(root);
    }
};

层序迭代法

思路

层序遍历一遍。

复杂度分析

时间复杂度:O(N)。

空间复杂度:O(N)。最平衡时最后一层可能有大约N/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 countNodes(TreeNode* root) {
        queue<TreeNode*> que;
        if(root != NULL) que.push(root);
        int count = 0;
        while(!que.empty()){
            int size = que.size();
            while(size--){
                TreeNode* node = que.front(); que.pop();
                count++;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        
        return count;
    }
};

探测剪枝递归法

思路

满二叉树的节点数为2^(Depth) - 1

利用完全二叉树特性,在完全二叉树基础上,探测子树最左侧一条和最右侧一条深度是否相等,判断子树是否为满二叉树。如果是,则向上返回计算出的节点数。

复杂度分析

时间复杂度:不明确,小于O(N),大于O(logN)。

空间复杂度:O(logN)。因为是完全二叉树,层数为logN级。

注意点

  1. 位运算1 << N,相当于2^N。或者想用2 << N时,要把N - 1
  2. 满二叉树节点数N = 2^h - 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* node) {
        if(node == NULL) return 0;
        TreeNode* left = node->left;
        TreeNode* right = node->right;
        int leftDepth = 1;	
        int rightDepth = 1;
        while(left){
            left = left->left;
            leftDepth++;
        }
        while(right){
            right = right->right;
            rightDepth++;
        }
        if(leftDepth == rightDepth) 
            return (1 << leftDepth) - 1; 
            // 节点数 = 2^层数 - 1
            // 1 << N 就是2^N (2的N次方)
        
        return countNodes(node->left) + countNodes(node->right) + 1;
    }
};

标签:node,right,TreeNode,val,16,int,二叉树,深度,left
From: https://www.cnblogs.com/tazdingo/p/18012244

相关文章

  • CF516D Drazil and Morning Exercise 题解
    Description给定一棵\(n\)个点的树,边有边权。定义\(f_x=\max_{i=1}^n\text{dist}(x,i)\)。\(q\)次询问最大的满足\(\max_{x\ins}f_x-\min_{x\ins}f_x\lel\)的连通块\(s\)包含的点数。\(n\le10^5\),\(q\le50\)。Solution这里\(f_u\)显然可以用换......
  • iPhone 16外观设计图曝光:重回iPhone X时代
    爆料人MajinBu在社交平台上曝光了iPhone16系列标准版设计图,有设计师依据设计图绘制了iPhone16渲染图。iPhone16最大变化是回归了iPhoneX时代的竖排双摄设计风格,提供了多彩配色,两颗摄像头分别是主摄和超广角。业内人士指出,iPhone16和iPhone16Plus之所以采用竖排双摄,是为......
  • 005_二叉树
    1.用递归和非递归的方式实现二叉树的先序、中序、后序遍历先序遍历递归publicvoidpreOrderRecur(TreeNoderoot){if(root==null){return;}System.out.println(root.val+"");preOrderRecur(root.left);preOrderRecur(root.right);}......
  • openGauss学习笔记-216 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-CPU
    openGauss学习笔记-216openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-CPU获取openGauss节点的CPU、内存、I/O和网络资源使用情况,确认这些资源是否已被充分利用,是否存在瓶颈点。216.1CPU通过top命令查看openGauss内节点CPU使用情况,分析是否存在由于CPU负载过高导致的性能......
  • (15/60)层序遍历、翻转二叉树、对称二叉树
    层序遍历leetcode:102.二叉树的层序遍历107.二叉树的层序遍历II199.二叉树的右视图637.二叉树的层平均值429.N叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的下一个右侧节点指针104.二叉树的最大深度111.二叉树的最小深度102.二叉树的层序遍......
  • 代码随想录算法训练营第十五天| 层序遍历 10 226.翻转二叉树 101.对称二叉树 2
    层序遍历  102.二叉树的层序遍历-力扣(LeetCode)思路:结合了昨天学到的标记法,每当一层遍历完,向队列中添加一个NULL标记。遍历到NULL节点表示该层遍历完了,将结果存入结果集中。/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNo......
  • P2585 [ZJOI2006] 三色二叉树
    原题链接总结1.要学会动态规划这种思维方式,即定义状态和状态之间的转移2.本题的难点在于如何将抽象的输入数据转换成树状结构处理和定义状态,这个定义状态让我想到了初中添加几何线,可能要多做题才能有感觉吧3.有一定模拟的部分,这一部分要细心\(Code\)#include<bits/stdc++.h>......
  • 核显第一次干掉GTX 1650!AMD锐龙7 8700G/锐龙5 8600G首发评测:AI生图算力6倍于入门独显
    一、前言:核显第一次斩落GTX1650此前很少有人会用核显玩3A游戏,AMD锐龙78700G的诞生改变了这一切!在移动端的锐龙97940HS上市之前,我们曾认为它的核显性能可以比肩GTX1650,毕竟有RDNA3构架加持,再加上GPU频率高达2800MHz。但实际表现并不及预期,只是略强于GTX1050Ti。2024年1月......
  • Go语言精进之路读书笔记第16条——理解Go语言的包导入
    Go编译速度快的原因主要体现在以下三方面:Go要求每个源文件在开头处显式地列出所有依赖的包导入,这样Go编译器不必读取和处理整个文件就可以确定其依赖的包列表。Go要求包之间不能存在循环依赖。这样一个包的依赖关系便形成了一张有向无环图。由于无环,包可以被单独编译,也可以并行......
  • 树与图的深度优先遍历
    #include<iostream>#include<algorithm>#include<cstring>usingnamespacestd;constintN=100010,M=N*2;intn;inth[N],e[M],ne[M],idx;boolst[N];intans=N;voidadd(inta,intb){e[idx]=b,ne[idx]=h[......