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

104.二叉树的最大深度

题目链接

思路:求最大深度也就是求根节点的高度,求高度用后序遍历,求深度用前序遍历。此题用后序遍历求高度比较容易。当我们需要从下往上返回信息的时候就应该用后序遍历。

class Solution {
public:
    int getdepth(TreeNode* node){//确定递归函数参数和返回值
        //确定终止条件
        if(node==nullptr) return 0;
        //单层递归逻辑,左中右
        int leftdepth=getdepth(node->left);
        int rightdepth=getdepth(node->right);
        int depth=1+max(leftdepth,rightdepth);
        return depth;       
    }
    int maxDepth(TreeNode* root) {
        return getdepth(root);
    }
};

此题也可以用简化的代码实现:

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==nullptr) return 0;
        return 1+max(maxDepth(root->left),maxDepth(root->right));
    }
};

559.n叉树的最大深度 

题目链接

注意遍历方式以及如何求最大值即可。

class Solution {
public:
    int maxDepth(Node* root) {
        if(root==NULL) return 0;
        int depth=0;
        vector children=root->children; 
        for(auto child:children){
            int cur=maxDepth(child);//继续递归遍历以该节点为根节点的子树,获取节点数量
            depth=max(depth,cur);//不断更新depth
        }
        return 1+depth;
    }
};

111.二叉树的最小深度

题目链接

思路:也是用后序遍历求高度的方法来求深度,注意此题有陷阱,单层递归逻辑里面不能直接返回左子树右子树高度的最小值,因为此题最小深度的定义是从根节点到最近叶子结点的最短路径上的节点数量,所以要排除只有左空或者右空的情况,因为叶子结点是左空右也空的,两个都不空就可以返回最小值+1。

class Solution {
public:
    int getdepth(TreeNode* node){//确定递归函数的参数和返回值
        if(node==NULL) return 0;//确定终止条件
        //单层递归的逻辑
        int leftdepth=getdepth(node->left);
        int rightdepth=getdepth(node->right);
        //接下来就有陷阱了,不能直接用min来求
        if(node->left!=NULL&&node->right==NULL){
            return 1+leftdepth;
        }
        else if(node->left==NULL&&node->right!=NULL){
            return 1+rightdepth;
        }
        else{
            int result=1+min(leftdepth,rightdepth);
            return result;
        }
    }
    int minDepth(TreeNode* root) {
        return getdepth(root);
    }
};

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

题目链接

普通二叉树解法:用后序遍历,遍历每个节点,最后得到节点个数。

class Solution {
public:
    int getnum(TreeNode* node){
        if(node==NULL) return 0;
        int ln=getnum(node->left);
        int rn=getnum(node->right);
        int result=1+ln+rn;
        return result;
    }
    int countNodes(TreeNode* root) {
        return getnum(root);
    }
};

利用完全二叉树的特性求解:此解法的关键在于如何判断二叉树是否为满二叉树。

满二叉树(深度为n)的节点数量是2^n-1。如果一个二叉树是满二叉树,那从根节点一直向左遍历的深度和一直向右遍历的深度是一样的,判断是满二叉树之后我们就终止递归,向上返回节点数量。如果不是,我们就继续向下遍历,遍历到满二叉树之后再向上返回。这样我们可以只遍历满二叉树的两侧,中间一些节点可以不用遍历。

class Solution {
public:
    int getnum(TreeNode* node){
        if(node==NULL) return 0;//一定要哟返回0,不然没法往上计数
        TreeNode*left=node->left;
        TreeNode*right=node->right;
        int lp=0,rp=0;//记录左侧深度和右侧深度
        while(left){
            left=left->left;
            lp++;
        }
        while(right){
            right=right->right;
            rp++;
        }
        if(lp==rp){//说明是满二叉树
            return (2<left);//向左去遍历得到左子树的节点数量
        int rn=getnum(node->right);
        return 1+ln+rn;
    }
    int countNodes(TreeNode* root) {
        return getnum(root);
    }
};

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