算法训练day12 | php | 104.二叉树的最大深度 , 559.n叉树的最大深度, 111.二叉树的最小深度, 222.完全二叉树的节点个数

一、力扣题104. 二叉树的最大深度

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

 方法一:递归法

        递归参数:二叉树节点;终止条件:节点为空;返回参数:该节点的深度。

        因为返回参数是当前节点的深度,父节点要获取当前深度,就需要拿到子节点的深度再加1,所以实际上就是从最底层的节点开始返回深度,每个父节点的深度都是子节点深度加1,但一个节点一般有左右两个子节点,故需对比两个子节点的深度,取深度更大的那个加1。

        所以单层递归逻辑是:先判断当前节点是否为空,为空return 0,不为空则继续,分别递归左右两个节点,将返回的左右节点的深度做对比,取更大的深度depth + 1 然后返回给上面的父节点。

function maxDepth($root) {
        if(!$root) return 0;

        $left = $this->maxDepth($root->left);
        $right = $this->maxDepth($root->right);

        return 1 + max($left, $right);
    }

方法二:递归法2

       二叉树的最大深度是根节点到叶子节点的最大节点数,也就是求最远叶子节点的深度。换句话说,根节点的高度就是二叉树的最大高度,等于最远叶子节点的最大深度,所以可以直接求根节点的最大高度。

        这次的逻辑是从上往下,每下到一个节点就加1,所以把深度设为递归的参数,将最大深度max改为全局变量,最大深度 max 的初始值的整型里的最小值,方便一开始的对比。

        递归参数:当前节点和深度; 终止条件:当前节点为空; 无返回参数。

        单层递归逻辑:先判断当前深度是否比全局变量的最大深度 max 大,是的话就把 max 改为当前深度。 然后将深度 + 1,递归存在的子节点。

class Solution {
    private $result = 1;
    /**
     * @param TreeNode $root
     * @return Integer
     */
    function maxDepth($root) {
        if(!$root) return 0;
        $this->max($root, 1);
        return $this->result;
    }

    function max($root, $depth) {
        if($depth > $this->result) $this->result = $depth;

        if($root->left) {
            $depth++;
            $this->max($root->left, $depth);
            $depth--;
        } 
        if($root->right) {
            $depth++;
            $this->max($root->right, $depth);
            $depth--;
        }
    }
}

方法三:迭代法

        使用层序遍历,每遍历一层深度+1即可。

function maxDepth($root) {
        $queue = new splQueue();
        if($root) $queue->enqueue($root);
        $sum = 0;

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $sum++;
            while($size--) {
                $cur = $queue->dequeue();
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
        }

        return $sum;
    }

二、力扣题111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。 

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示:

  • 树中节点数的范围在 [0, 105] 内
  • -1000 <= Node.val <= 1000

方法一:递归法

        和上面的递归法逻辑差不多,不同之处在于返回的深度是取左右节点中更小的深度+1,另外只递归存在的节点,不会递归不存在 的节点,递归不存在的节点会影响min()函数的判断。

function minDepth($root) {
        if(!$root) return 0;
        return $this->min($root);
    }

    function min($root) {
        if($root->left === null && $root->right === null) return 1;

        if($root->left && $root->right) {
            $left = $this->min($root->left);
            $right = $this->min($root->right);
            return 1 + min($left, $right);
        }
        if($root->left) return $this->min($root->left) + 1;
        if($root->right) return $this->min($root->right) + 1;
    }

        也有更简洁的写法

function minDepth($root) {
        if(!$root) return 0;
        return $this->min($root);
    }

    function min($root) {
        if($root->left === null && $root->right === null) return 1;
        $left = $this->minDepth($root->left);
        $right = $this->minDepth($root->right);

        if($root->left && $root->right) {
            return 1 + min($left, $right);
        }
        if($root->left) return $left + 1;
        return $right + 1;
    }

方法二:递归法2

        逻辑和最大深度的递归法2没有区别,同样设置一个全局变量 min ,初始值为整型里的最大值,然后在递归中不断对比获取更小的深度,终止条件依旧为节点是叶子节点的时候。

class Solution {
    private $result = PHP_INT_MAX;
    /**
     * @param TreeNode $root
     * @return Integer
     */
    function minDepth($root) {
        if(!$root) return 0;
        $this->res($root, 1);
        return $this->result;
    }

    function res($root, $depth) {
        if($root->left === null && $root->right === null) {
            $this->result = min($depth, $this->result);
            return;
        }

        if($root->left) {
            $this->res($root->left, $depth + 1);
        }
        if($root->right) {
            $this->res($root->right, $depth + 1);
        }

        return;
    }
}

方法三:迭代法

        使用层序遍历,每遍历一层深度都 + 1,知道遍历到的节点为叶子节点时,直接返回当前深度即可。

function minDepth($root) {
        $queue = new splQueue();
        if(!$root) return 0;
        $queue->enqueue($root);
        $sum = 0;

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $sum++;

            while($size--) {
                $cur = $queue->dequeue();
                if($cur->left === null && $cur->right === null) {
                    return $sum;
                }
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
        } 
    }

三、力扣题222. 完全二叉树的节点个数

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

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

示例 1:

输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

输入:root = []
输出:0

示例 3:

输入:root = [1]
输出:1

提示:

  • 树中节点的数目范围是[0, 5 * 104]
  • 0 <= Node.val <= 5 * 104
  • 题目数据保证输入的树是 完全二叉树

 方法一:迭代法

        这道题直接用层序遍历是最容易想到的,直接每将一个节点入队列时,总和就加一,当判断到空节点时,直接return即可。

unction countNodes($root) {
        if(!$root) return 0;
        $queue = new splQueue();
        $queue->enqueue($root);
        $sum = 0;

        while(!$queue->isEmpty()) {
            $size = $queue->count();
            $sum += $size;

            while($size--) {
                $cur = $queue->dequeue();
                if($cur->left) $queue->enqueue($cur->left);
                if($cur->right) $queue->enqueue($cur->right);
            }
        }

        return $sum;
    }

方法二:递归法

        使用全局变量统计节点个数,递归节点时遵循左、右节点的顺序,因为是完全二叉树,当递归到空节点时,说明全部节点已经遍历完毕,直接return。

class Solution {
    private $sum = 0;
    /**
     * @param TreeNode $root
     * @return Integer
     */
    function countNodes($root) {
        if(!$root) return 0;
        $this->sum++;

        $this->countNodes($root->left);
        $this->countNodes($root->right);

        return $this->sum;
    }
}

方法三:递归法2

        看题解的,非常简洁,简洁到一开始看着没有头绪,然后神奇地发现这样真的可以。

function countNodes($root) {
        if(!$root) return 0;
        return 1 + $this->countNodes($root->left) + $this->countNodes($root->right);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值