代码随想录第16天 | 二叉树part03

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

题目一 104.二叉树的最大深度 559.n叉树的最大深度

part7 二叉树的最大深度

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

注意:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)深度是从上开始向下计算。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)高度是从下开始向上计算。

可得,根节点的高度就是二叉树的最大深度.
本题中我们通过后序求的根节点高度来求的二叉树最大深度。

定单层递归的逻辑:
先求它的左子树的深度,再求右子树的深度,
最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)
就是目前节点为根节点的树的深度。
这种思路对多叉树也一样,对每个分叉的长度拉成一个数组,再取最大值。

class Solution 
{
    public int maxDepth(TreeNode root) {
        return get(root);
    }
    
    public int get(TreeNode root)
    {
        if(root == null)
            return 0;
        int leftnum = get(root.left);
        int rightnum = get(root.right);

        return 1 + Math.max(leftnum, rightnum);
    }
}

前序遍历的思路如下(中左右),需要考虑回溯:

public class solution 
{
    public int result;
    public void getdepth(TreeNode node, int depth) 
    {
        result = depth > result ? depth : result; // 中

        if (node.left == null && node.right == null) 
	        return ;

        if (node.left != null) 
        { // 左
            depth++;    // 深度+1
            getdepth(node.left, depth);
            depth--;    // 回溯,深度-1
        }
        if (node.right != null) 
		{ // 右
            depth++;    // 深度+1
            getdepth(node.right, depth);
            depth--;    // 回溯,深度-1
        }
        return ;
    }
    public int maxDepth(TreeNode root) 
    {
        result = 0;
        if (root == null)
	        return result;
	        
        getdepth(root, 1);
        return result;
    }
};

迭代法,使用层序遍历正好,因为计算的是层数。
注意是迭代,所以有for循环。

public class solution 
{
	public int maxDepth(Treenode root)
	{
		if(root == null)
			return 0;
		int depth = 0;
		Queue<Treenode> que = new LinkedList<>();
		que.push(root);
		while(que.isEmpty() != true)
		{
			int len = que.size();
			depth++;
			for(int i=0; i<len; i++)
			{
				Treenode popnode = que.front();
				que.pop();
				if(popnode.left != null)
				que.push(root.left);
				if(popnode.rigth != null)
				que.push(root.right);
			}
			
		}
		return depth;
	}
}

题目二 111.二叉树的最小深度

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

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。注意是叶子节点
什么是叶子节点,左右孩子都为空的节点才是叶子节点!
首先根节点自己如果左右节点仅缺少一个,也不能将自己视为叶子节点,必须接着向下寻找。
因此目标为,找到一个离根节点最近的叶子节点。
同样使用递归,关键是特殊情况:
左空,右不空,不是最低点;
右空,左不空,不是最低点;

class Solution {
    public int minDepth(TreeNode root) 
    {
        if(root == null)
            return 0;
        int leftnum = minDepth(root.left);
        int rightnum = minDepth(root.right);
        
        if(root.left == null && root.right != null)
            return 1 + rightnum;
        if(root.left != null && root.right == null)
            return 1 + leftnum;
        int depth = 1 + Math.min(leftnum, rightnum);
        
        return depth;
    }
}

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

给出一个完全二叉树,求出该树的节点个数。
示例 1:

  • 输入:root = [1,2,3,4,5,6] 输出:6
    示例 2:
  • 输入:root = [] 输出:0

首先用迭代法的话,根据完全二叉树的性质,用层序遍历正好能按顺序遍历。
这是一种方法。

class Solution {
    public int countNodes(TreeNode root) 
    {
        if(root == null)
            return 0;
        Queue<TreeNode> que = new LinkedList<>();
        que.offer(root);
        int count = 0;
        while(que.isEmpty() != true)
        {
            int len = que.size();
            for(int i=0; i<len; i++)
            {
                TreeNode popnode = que.poll();
                
                count++;
                if(popnode.left != null)
                    que.offer(popnode.left);
                if(popnode.right != null)
                    que.offer(popnode.right);
            }
        }
        return count;
    }
}

而使用递归,上面的两种方法,我们使用后序遍历的时候,每次获取左右子树的根节点深度,再取它们之间的最大/最小值;而如果要计算全部节点数量,则只需将它们全部加起来,再加上根节点即可。

  • 时间复杂度:O(n)
  • 空间复杂度:O(log n),算上了递归系统栈占用的空间
class Solution 
{
    public int countNodes(TreeNode root) 
    {
        if(root == null)
            return 0;
        int leftnum = countNodes(root.left);
        int rightnum = countNodes(root.right);

        int num = leftnum + rightnum + 1;
        return num;
    }
}
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值