首页 > 其他分享 >二叉树的最大宽度系列问题

二叉树的最大宽度系列问题

时间:2022-11-05 19:56:05浏览次数:84  
标签:系列 int max pos depth 宽度 二叉树 节点

二叉树的最大宽度系列问题

作者:Grey

原文地址:

博客园:二叉树的最大宽度系列问题

CSDN:二叉树的最大宽度系列问题

求树的最大宽度

题目描述

给你一棵二叉树的根节点 root ,返回树的最大宽度 。
树的最大宽度是所有层中最大的宽度 。
每一层的宽度被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。
将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。

题目链接:LeetCode 662. Maximum Width of Binary Tree

主要思路

由于求宽度的时候,可以把这个二叉树视作满二叉树,所以在原先的 TreeNode 基础上,封装一个数据结构

    static class AnnotateNode {
        TreeNode treeNode;
        int depth;
        int pos;

        public AnnotateNode(TreeNode treeNode, int depth, int pos) {
            this.treeNode = treeNode;
            this.depth = depth;
            this.pos = pos;
        }
    }

这个数据结构增加了两个数据项:

depth:表示一个 TreeNode 节点在第几层。

pos:表示一个 TreeNode 节点在当前层排第几(注:空节点也算)。

以一颗二叉树举例,如下示例图,以两个节点来说明封装的 AnnotateNode,虚线节点是 null 节点。

image

对于一棵满二叉树来说,如果当前节点是 depth,pos,那么其左孩子就是 depth + 1pos * 2;右孩子就是 depth + 1pos * 2 + 1

接下来,并把每个位置的 pos,depth 指标记录到 AnnotateNode 节点中。

参考二叉树的按层遍历对二叉树进行遍历,在下一层开始结算上一层的结果

而且每次要记录上一层的最左位置 left,在一层结束时,记录一个最右侧位置 right,然后设置一个全局最大的 max,max 的更新策略就是

max = Math.max(max, right - left + 1)

完整代码见

class Solution {
        public int widthOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int max = 1;
        Queue<AnnotateNode> queue = new LinkedList<>();
        queue.offer(new AnnotateNode(root, 0, 0));
        int curDepth = 0;
        int left = 0;
        while (!queue.isEmpty()) {
            AnnotateNode node = queue.poll();
            if (node.treeNode != null) {
                queue.offer(new AnnotateNode(node.treeNode.left, node.depth + 1, node.pos * 2));
                queue.offer(new AnnotateNode(node.treeNode.right, node.depth + 1, node.pos * 2 + 1));
                if (curDepth != node.depth) {
                    curDepth = node.depth;
                    left = node.pos;
                }
                int right = node.pos;
                max = Math.max(max, right - left + 1);
            }
        }
        return max;
    }

    static class AnnotateNode {
        TreeNode treeNode;
        int depth;
        int pos;

        public AnnotateNode(TreeNode treeNode, int depth, int pos) {
            this.treeNode = treeNode;
            this.depth = depth;
            this.pos = pos;
        }
    }
}

求树的最大宽度的有效节点个数

题目描述

给定一个二叉树,你需要编写一个函数来获取这课树的最大宽度,二叉树的最大宽度是指具有节点数最多的那一层的结点个数。

题目链接见:牛客-二叉树的最大宽度

与上一个问题不同,本题求的最大宽度是有效节点的个数,所以是不包括 null 节点的。

主要思路

可以使用哈希表,并且按照层次遍历的方法,存下每一层的节点个数。不过还有更省空间的做法,设置有限几个变量,无需申请一个哈希表

// 当前层的结尾节点,初始为 head 
TreeNode curEnd = head;
// 下一层的结尾节点,初始为 null
TreeNode nextEnd = null;
// 当前层的节点个数,初始化为 0
int curLevelNodes = 0;

然后也是二叉树的按层遍历对二叉树进行遍历,遍历过程中,如果遍历到的当前节点 c 满足 c == curEnd,即:当前节点就是当前结尾位置的节点,则可以确定一层结束,更新全局 max,当前层节点个数归零,即 curLevelNodes = 0,并将下层结尾节点赋值给 curEnd

max = Math.max(curLevelNodes, max);
curLevelNodes = 0;
curEnd = nextEnd;

完整代码见

public class Solution {

   public  int getMaxWidth(TreeNode head) {
        if (head == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        int max = 1;
        queue.offer(head); 
        TreeNode curEnd = head;
        TreeNode nextEnd = null;
        int curLevelNodes = 0;
        while (!queue.isEmpty()) {
            TreeNode c = queue.poll();
            if (c.left != null) {
                queue.offer(c.left);
                nextEnd = c.left;
            }
            if (c.right != null) {
                queue.offer(c.right);
                nextEnd = c.right;
            }
            curLevelNodes++;
            // 当前节点已经到结束了
            if (c == curEnd) {
                max = Math.max(curLevelNodes, max);
                curLevelNodes = 0;
                curEnd = nextEnd;
            }
        }
        return max;
    }
}

更多

算法和数据结构笔记

标签:系列,int,max,pos,depth,宽度,二叉树,节点
From: https://www.cnblogs.com/greyzeng/p/16860946.html

相关文章

  • 105. 从前序与中序遍历序列构造二叉树
    给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。示例1:  输入:pre......
  • ZYNQ7000系列 PS、PL、AXI 、启动流程基本概念篇
    FPGA系统性学习笔记连载_Day4XilinxZYNQ7000系列PS、PL、AXI、启动流程基本概念篇本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群......
  • 二叉树的遍历总结
    二叉树的遍历总结前序:https://leetcode.cn/problems/binary-tree-preorder-traversal/中序:https://leetcode.cn/problems/binary-tree-inorder-traversal/后序:https://l......
  • 【随机过程】随机过系列之非平稳过程
    非平稳过程有很多种,这里介绍两种:周期(循环)平稳过程和正交增量过程。说实话这一讲听的迷迷糊糊的,如果后面有新的理解会做补充。周期平稳$R_X(t,s)=R_X(t+T,s+T),\exist......
  • Java的List之坑系列--ArrayList的浅拷贝问题
    简介    本文介绍ArrayList的浅拷贝问题的原因和解决方案。    问个问题:先newArrayList创建了list1并用add添加对象,再newArrayList创建了list2,然后list2.......
  • #yyds干货盘点#【愚公系列】2022年11月 微信小程序-(rich-text)富文本和(text)文本的
    前言富文本格式(RichTextFormat)即RTF格式,又称多文本格式,是由微软公司开发的跨平台文档格式。大多数的文字处理软件都能读取和保存RTF文档。它是一种方便于不同的设备、系......
  • 【线性代数】抽丝剥茧系列汇总篇
    耗时两周,说长不长,说短不短,总算肝完了。ProfessorStrang讲的线代真的深入浅出,这次算是真正线性代数入了门,看到与线代相关的东西不会怯了!目录:【线性代数】抽丝剥茧系列......
  • Nextflow系列 入门
    一、Nextflow1、Nextflow介绍Nextflow是西班牙巴塞罗那的生物医学和基因组学研究中心CRG开发的开源workflow引擎。是基于Groovy语言的一种工作流框架,能够大大简化复杂计......
  • LeetCode 145. 二叉树的后序遍历
    问题描述给定一个二叉树,返回它的后序遍历。示例:进阶:递归算法很简单,你可以通过迭代算法完成吗?题目代码/***Definitionforabinarytreenode.*publicclassTre......
  • 【不费脑筋系列】发布个人的代码包到Nuget服务器上,并通过VS引用进行使用的方法...
    打打酱油,写点不需要费脑筋的博客先压压惊。下面讲个关于个人如何开发nuget包,并部署到nuget服务器上的例子。为了保证.netframework和.netcore都可以访问到我的包,我此处......