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

104.二叉树的最大深度

思路:二叉树求深度:从上往下遍历,前序遍历        求高度:从下往上遍历,后序遍历

本题的求最大高度和最大深度都一样,高度即深度。

以下用后序遍历求深度,每层递归返回左右子树最大的高度加上本身(当前根节点)的高度.

代码:

int getdepth(TreeNode* node){
        if(node == nullptr) return 0;
        int leftdepth = getdepth(node->left);//左
        int rightdepth = getdepth(node->right);//右
        return 1 + max(leftdepth,rightdepth);//中,返回当前节点(包含当前节点)的最大高度(深度)给上一层
    }
    int maxDepth(TreeNode* root) {
        return getdepth(root);
    }

559.n叉树的最大深度

思路:求n叉树和二叉树的最大深度本质是一样的,都是为了求最大的层数.二叉树求最大深度的思路是求出左右子树的最大深度再加上根节点一层就是该树的最大深度。n叉树求最大深度和二叉树思路一样,求出各个子树的最大深度再加上根节点就是该树的最大深度。难点还是在于如何用孩子节点进行递归。二叉树有清晰的左右孩子,而n叉树没有所谓的左右孩子,即可能有n个孩子。可以用一个for循环,分别求出每个孩子的最大深度,依次递归。

代码:

int maxDepth(Node* root) {
       if(root == 0) return 0;
       int depth = 0;
       for(int i = 0;i < root->children.size();i++){
           depth = max(depth,maxDepth(root->children[i]));//比较节点下的最大高度
       } 
       return depth+1;
    }

111.二叉树的最小深度

当根节点左右孩子有一个为空的时候,不能算高度为1(根节点)。可以理解为需要算除根节点为,左右子树的最小高度,最后高度再加1即为最小高度。

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

思路:该题用后序遍历,求最小高度和最小深度在该题都是符合题意。但是需要注意在中的时候处理情况需要分开判断。

代码:

int getDepth(TreeNode* node){
        if(node == nullptr) return 0;
        int leftDepth = getDepth(node->left);//左,获取左子树高度
        int rightDepth = getDepth(node->right);//右,获取右子树高度
        //中
        if(node->left==nullptr && node->right!=nullptr)
            return 1+rightDepth;
        if(node->left!=nullptr && node->right==nullptr)
            return 1+leftDepth;
        return 1+min(leftDepth,rightDepth);//排除以上情况,该情况是左右都不为空时,把高度小的子树+1返回
    }
    int minDepth(TreeNode* root) {
        return getDepth(root);
    }

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

首先可以先做下计算普通二叉树节点个数的解法,后序遍历。

完全二叉树的节点数计算也可以用普通二叉树的方法计算,由于该解法是遍历了所有节点,所以时间复杂度O(n)。

代码:

int getNodeNums(TreeNode* node){
        if(node == nullptr) return 0;
        int leftNums = getNodeNums(node->left);//左
        int rightNums = getNodeNums(node->right);//右
        int result = leftNums + rightNums + 1;//中,左子树节点数+右子树节点数+根节点一个
        return result;
    }
    int countNodes(TreeNode* root) {
        return getNodeNums(root);
    }

该题考察的是利用完全二叉树的特性去解

思路:完全二叉树是有可能为满二叉树的,若是满二叉树可以利用公式计算节点,而不需要一个个遍历。完全二叉树有可能由多个满二叉子树构成,若整体的树不是满二叉树可以分解左右有两颗子树判断是否为满二叉树。

如何判断是不是满二叉树?可以从根节点出发,往外两遍遍历计算高度.若高度相同则是满二叉树。该判断的解法是因为该题是完全二叉树,所以若高度相同,树中间是不可能为空的。

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

代码:

int getNodeNums(TreeNode* node){
        if(node == nullptr) return 0;//终止条件1
        TreeNode* left_node = node->left;//终止条件2,判断子树是不是满二叉树,若是则用公式计算
        TreeNode* right_node = node->right;
        int leftDepth = 0;//最左边高度
        int rightDepth = 0;//最右边高度
        while(left_node){
            leftDepth++;
            left_node = left_node->left;
        }
        while(right_node){
            rightDepth++;
            right_node = right_node->right;
        }
        if(leftDepth == rightDepth) return (2<left);//左
        int rightNodeNums = getNodeNums(node->right);//右
        int result = leftNodeNums + rightNodeNums + 1;//中
        return result;
    }
    int countNodes(TreeNode* root) {
        return getNodeNums(root);
    }

该解法当完全二叉树足够大时,可以少计算很多树中间的节点。

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