首页 > 编程语言 >【字节二面算法】NO662 二叉树最大宽度

【字节二面算法】NO662 二叉树最大宽度

时间:2023-05-01 10:45:35浏览次数:76  
标签:NO662 poll 二面 queue 二叉树 ans var null root

[字节二面算法] 662. 二叉树最大宽度

给你一棵二叉树的根节点 root ,返回树的 最大宽度 。

树的 最大宽度 是所有层中最大的 宽度 。

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

题目数据保证答案将会在 32 位 带符号整数范围内。

示例 1:

image-20230501102216617
输入:root = [1,3,2,5,3,null,9]
输出:4
解释:最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9) 。

示例 2:

输入:root = [1,3,2,5,null,null,9,6,null,7]
输出:7
解释:最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7) 。

示例 3:

image-20230501102251707
输入:root = [1,3,2,5]
输出:2
解释:最大宽度出现在树的第 2 层,宽度为 2 (3,2) 。

提示:

  • 树中节点的数目范围是 [1, 3000]
  • -100 <= Node.val <= 100
暴力模拟空节点(超时
class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        var ans = 0;
        if (root == null) {
            return ans;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            var count = queue.size();
            var widthCount = 0;
            var nullCount = 0;
            boolean flag = false;
            while(count-- > 0) {
                TreeNode poll = queue.poll();
                if(poll != null) {
                    System.out.print(poll.val + " ");
                    flag = true;
                    queue.add(poll.left);
                    queue.add(poll.right);

                    widthCount += nullCount + 1;
                    nullCount = 0;
                } else {
                    System.out.print("* ");
                    queue.add(null);
                    queue.add(null);
                    if(widthCount > 0) {
                        nullCount++;
                    }
                }
            }
            System.out.println();
            if(!flag) {
                break;
            }

            ans = Math.max(widthCount, ans);
        }
        return ans;
    }
}
利用层序遍历的性质

​ 记录节点的编号,然后用同一层的最大节点编号减去最小然后+1就是该层的最大宽度了。

class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        var ans = 0;
        if (root == null) {
            return ans;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        Map<TreeNode, Long> map = new HashMap<>();
        map.put(root, 1L);
        while (!queue.isEmpty()) {
            var count = queue.size();
            var min = Long.MAX_VALUE;
            var max = Long.MIN_VALUE;
            while(count-- > 0) {
                TreeNode poll = queue.poll();
                var cur = map.get(poll);
                min = Math.min(min, cur);
                max = Math.max(max, cur);
                if(poll.left != null) {
                    queue.add(poll.left);
                    map.put(poll.left, cur * 2);
                }
                if(poll.right != null) {
                    queue.add(poll.right);
                    map.put(poll.right, cur * 2 + 1);
                }
            }
            ans = (int) Math.max(ans, max - min + 1);
        }
        return ans;
    }
}
原来可以这么写。。

​ 和上面的思路是一样的,这题并不难,其实最开始也想到用编号的方法,但是想着给的树节点定义是改变不了的,所以模拟超时之后又想到了使用map,然后看到别人其实是直接定义一个新类嵌套了树节点,这样的话就省去了map集合的操作时间消耗,学到了学到了

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public class QueueNode {
        TreeNode root;
        long index;

        QueueNode(TreeNode root, long index) {
            this.root = root;
            this.index = index;
        }
    }

    public int widthOfBinaryTree(TreeNode root) {
        if (root == null) {
            return 0;
        }
        var ans = 1;
        Queue<QueueNode> queue = new LinkedList<>();
        queue.add(new QueueNode(root, ans));
        while(!queue.isEmpty()) {
            var size = queue.size();
            var first = 0L;
            var last = 0L;
            for(var i = 0; i < size; i++) {
                QueueNode poll = queue.poll();
                var index = poll.index;
                if(i == 0) {
                    first = index;
                    // 注意这里
                    last = index;
                } else if (i == size - 1 ){
                    last = index;
                }
                var left = poll.root.left;
                var right = poll.root.right;
                if(left != null) {
                    queue.add(new QueueNode(left, index * 2));
                }
                if(right != null) {
                    queue.add(new QueueNode(right, index * 2 + 1));
                }
            }
            ans = (int) Math.max(ans, last - first + 1);
        }
        return ans;
    }
}

标签:NO662,poll,二面,queue,二叉树,ans,var,null,root
From: https://www.cnblogs.com/tod4/p/17366245.html

相关文章

  • Java层序遍历打印二叉树(有Null值)
    publicclassSolution{publicstaticvoidmain(String[]args){Integer[]arr={3,9,20,null,null,15};//根据数组构造出二叉树TreeNodetreeNode=creatTreeNode(arr,0);//层序有Null值的打印二叉树printBin......
  • 线索化二叉树的递归算法
    //线索化二叉树的递归算法#include<stdio.h>#include<malloc.h>typedefstructBiTNode{intdata;structBiTNode*lchild,*rchild;//存储二叉树的左孩子和右孩子}BiTNode,*BiTree;typedefstructThreadNode{intdata;structThreadNode*......
  • Java根据Integer数组(有null值)递归构造二叉树
    二叉树:publicclassTreeNode{intval;TreeNodeleft;TreeNoderight;TreeNode(){}TreeNode(intval){this.val=val;}TreeNode(intval,TreeNodeleft,TreeNoderight){this.val=val;this.l......
  • 字节后端一二面,讯飞一面
    1.自我介绍2.rdbaof3.线程池4.ping命令用了什么协议5.应用层的协议6.为什么四次挥手要timewait7.算法题:和为k的子数组个数(前缀和)8.幻读7.隔离级别8.tcp相关的一些东西2.21二面:1.介绍2.项目一些问题3.springboot里面有什么4.注册中心有了解过吗5.之前的项目用到了spr......
  • 二叉树Binary Tree
    二叉树BinaryTree1.树的一些常用术语2.二叉树的概念树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树;二叉树的子节点分为左子节点和右子节点;以下三种均为二叉树:若该二叉树的所有叶子节点都在最后一层,且节点总数n==\(2^k\)-1,k为层数,则称为满二叉树......
  • 23-4-27--二叉树--玩转二叉树
    给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。输入格式:输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行......
  • 实现二叉树结点的新建、查找、修改
     如果需要新建结点(例如往二叉树里面插入结点时,可使用下面的函数(返回类型是一个指向node的指针)node*newNode(intv){nodeNode=newnode;//申请一个node类型变量的地址空间Node->data=v;//结点权值为vNode->lchild=Node->rchild=NULL;//初始状态下无左右孩子retur......
  • 请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来....
    先转载过来以后再研究importjava.io.*;importjava.util.Stack;publicclassmyTest{privatemyTreetree;/***二叉树的插入,参数为(关键字,数据)***/publicvoidinsert(intkey,intdata......
  • 山东大学数据结构实验9 二叉树操作
    描述创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。格式输入格式第一行为一个数字n(10<=n<=100000),表示有这棵树有n个节点,编号为1~n。之后n行每行两个数字,第i行的两个数字a、b表示编号......
  • 数据结构——二叉树
    数据结构(十四)——二叉树一、二叉树简介1、二叉树简介二叉树是由n(n>=0)个结点组成的有序集合,集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。二叉树的五种形态:2、二叉树的存储结构模型树的另一种表示法:孩子兄弟表示法A、每个结点都有一个......