Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2023-06-08:给你一棵二叉树的根节点 root ,返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每

2023-06-08:给你一棵二叉树的根节点 root ,返回树的 最大宽度 。 树的 最大宽度 是所有层中最大的 宽度 。 每

作者头像
福大大架构师每日一题
发布于 2023-06-09 02:50:41
发布于 2023-06-09 02:50:41
23400
代码可运行
举报
运行总次数:0
代码可运行

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

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

每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。

将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,

这些 null 节点也计入长度。

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

输入:root = [1,3,2,5,3,null,9]。

输出:4。

答案2023-06-09:

大体步骤如下:

该算法使用一个容器来存储节点的信息,每个节点信息包含节点本身和其在满二叉树中的位置。

1.如果root为空,返回0,否则初始化一个变量ans来记录最大宽度。

2.使用一个队列queue来存储节点信息,将根节点的信息{root,1}加入队列。

3.循环处理队列,每次处理一层,对于每个节点:

  • • a.pop出队列中的节点信息,将该节点作为当前节点cur。
  • • b.如果当前节点是该层的第一个节点,则记录其Index为left。
  • • c.如果当前节点是该层的最后一个节点,则记录其Index为right。
  • • d.如果当前节点有左孩子,则将其左孩子信息{cur.Node.Left,cur.Index*2}加入队列。
  • • e.如果当前节点有右孩子,则将其右孩子信息{cur.Node.Right,cur.Index*2+1}加入队列。

4.计算当前层的宽度,将其记录为max(right-left+1,ans)。

5.返回最大宽度ans。

时间复杂度:每个节点仅仅入队、出队各一次,因此时间复杂度为O(N),其中N为树中节点的数量。

空间复杂度:本算法使用了一个队列来存储节点信息,队列中的节点数量不会超过两层的节点数,因此空间复杂度为O(2^h),其中h为树的高度。如果是完全二叉树,h=logN,空间复杂度为O(N)。

golang完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
    "container/list"
    "fmt"
)

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

type Info struct {
    Node  *TreeNode
    Index int
}

func widthOfBinaryTree(root *TreeNode) int {
    if root == nil {
        return 0
    }

    var ans, left, right int
    queue := list.New()
    queue.PushBack(&Info{Node: root, Index: 1})
    for queue.Len() > 0 {
        size := queue.Len()
        for i := 0; i < size; i++ {
            cur := queue.Front().Value.(*Info)
            queue.Remove(queue.Front())
            if i == 0 {
                left = cur.Index
            }
            if i == size-1 {
                right = cur.Index
            }
            if cur.Node.Left != nil {
                queue.PushBack(&Info{Node: cur.Node.Left, Index: cur.Index * 2})
            }
            if cur.Node.Right != nil {
                queue.PushBack(&Info{Node: cur.Node.Right, Index: cur.Index*2 + 1})
            }
        }
        ans = max(ans, right-left+1)
    }
    return ans
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func main() {
    root := &TreeNode{
        Val: 1,
        Left: &TreeNode{
            Val: 3,
            Left: &TreeNode{
                Val: 5,
            },
        },
        Right: &TreeNode{
            Val: 2,
            Right: &TreeNode{
                Val: 3,
                Right: &TreeNode{
                    Val: 9,
                },
            },
        },
    }
    fmt.Println(widthOfBinaryTree(root))
}

在这里插入图片描述

c++完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <queue>

using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};

struct Info {
    TreeNode* node;
    int index;
    Info(TreeNode* n, int i) : node(n), index(i) {};
};

int widthOfBinaryTree(TreeNode* root) {
    if (!root) {
        return 0;
    }
    int ans = 1;
    int leftmost_idx, rightmost_idx;

    queue<Info> q;
    q.push(Info(root, 1));

    while (!q.empty()) {
        int level_size = q.size();
        leftmost_idx = q.front().index, rightmost_idx = q.front().index;

        for (int i = 0; i < level_size; i++) {
            Info cur = q.front();
            q.pop();

            leftmost_idx = min(leftmost_idx, cur.index);
            rightmost_idx = max(rightmost_idx, cur.index);

            if (cur.node->left) {
                q.push(Info(cur.node->left, cur.index << 1));
            }
            if (cur.node->right) {
                q.push(Info(cur.node->right, (cur.index << 1) | 1));
            }
        }

        ans = max(ans, rightmost_idx - leftmost_idx + 1);
    }

    return ans;
}

int main() {
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(3);
    root->right = new TreeNode(2);
    root->left->left = new TreeNode(5);
    root->left->right = nullptr;
    root->right->left = new TreeNode(3);
    root->right->right = new TreeNode(9);

    cout << widthOfBinaryTree(root) << endl; 

    return 0;
}

在这里插入图片描述

c语言完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct TreeNode {
    int val;
    struct TreeNode* left;
    struct TreeNode* right;
};

struct TreeNode* newTreeNode() {
    struct TreeNode* ans = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    ans->val = 0;
    ans->left = NULL;
    ans->right = NULL;
    return ans;
};

struct Info {
    struct TreeNode* node;
    int index;
};

int widthOfBinaryTree(struct TreeNode* root) {
    if (!root) {
        return 0;
    }
    int ans = 1;
    int leftmost_idx, rightmost_idx;

    struct Info init = { root, 1 };
    struct Info cur;
    struct TreeNode* node;
    struct Info* q = newTreeNode();
    int head = 0, tail = 0;
    q[head++] = init;

    while (head != tail) {
        int level_size = head - tail;
        leftmost_idx = q[tail].index, rightmost_idx = q[tail].index;

        for (int i = 0; i < level_size; i++) {
            cur = q[tail++];

            leftmost_idx = leftmost_idx < cur.index ? leftmost_idx : cur.index;
            rightmost_idx = rightmost_idx > cur.index ? rightmost_idx : cur.index;

            node = cur.node;
            if (node->left) {
                q = (struct Info*)realloc(q, sizeof(struct Info) * (head + 1));
                q[head++] = (struct Info){ node->left, cur.index << 1 };
            }
            if (node->right) {
                q = (struct Info*)realloc(q, sizeof(struct Info) * (head + 1));
                q[head++] = (struct Info){ node->right, (cur.index << 1) | 1 };
            }
        }

        ans = max(ans, rightmost_idx - leftmost_idx + 1);
    }

    free(q);

    return ans;
}

int main() {
    struct TreeNode* root = newTreeNode();
    root->val = 1;
    root->left = newTreeNode();
    root->left->val = 3;
    root->right = newTreeNode();
    root->right->val = 2;
    root->left->left = newTreeNode();
    root->left->left->val = 5;
    root->left->right = NULL;
    root->right->left = newTreeNode();
    root->right->left->val = 3;
    root->right->right = newTreeNode();
    root->right->right->val = 9;

    printf("%d\n", widthOfBinaryTree(root));

    free(root->left->left);
    free(root->left);
    free(root->right->left);
    free(root->right->right);
    free(root->right);
    free(root);

    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表 如果在二叉树中,存在一条一直向下的路径 且每个点的数值恰好一一对应
2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表
福大大架构师每日一题
2023/05/10
4370
2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表 如果在二叉树中,存在一条一直向下的路径 且每个点的数值恰好一一对应
LeetCode 431. 将 N 叉树编码为二叉树(递归/层序)
设计一个算法,可以将 N 叉树编码为二叉树,并能将该二叉树解码为原 N 叉树。 一个 N 叉树是指每个节点都有不超过 N 个孩子节点的有根树。 类似地,一个二叉树是指每个节点都有不超过 2 个孩子节点的有根树。 你的编码 / 解码的算法的实现没有限制,你只需要保证一个 N 叉树可以编码为二叉树且该二叉树可以解码回原始 N 叉树即可。
Michael阿明
2021/02/19
7410
2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个从 1 到 n 且互不相同的值 另给你一个长度为 m
返回一个长度为 m 的数组 answer ,其中 answeri 是执行第 i 个查询后树的高度。
福大大架构师每日一题
2023/05/03
3480
2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个从 1 到 n 且互不相同的值 另给你一个长度为 m
[数据结构]二叉树OJ(leetcode)
---- 二叉树OJ(leetcode)训练习题:: 1.单值二叉树 //单值二叉树 //思路:相等的传递性 struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; }; bool isUnivalTree(struct TreeNode* root) { if (root == NULL) return true; if (root->left && root->val != root->lef
IT编程爱好者
2023/04/12
2300
[数据结构]二叉树OJ(leetcode)
【代码随想录】二刷-二叉树
二叉树中章节中,相对于迭代,递归有时候会更好理解,部分题用到了马上要刷的回溯算法。
半生瓜的blog
2023/05/13
8460
【代码随想录】二刷-二叉树
2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中
2.定义一个结构体类型 TreeNode,表示二叉树的节点,包括节点值 Val,左子节点 Left,右子节点 Right。
福大大架构师每日一题
2023/06/21
2200
2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中
DFS基础问题-LeetCode 98、101(二叉树中序遍历,层次遍历)
假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数。 节点的右子树只包含大于当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。
算法工程师之路
2019/09/17
8060
【数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
下面的函数 buildTree 用于根据给定的括号表示串来构建二叉树,思路是通过解析字符串,递归地构建各个节点及其子树
Rossy Yan
2024/12/24
1020
【数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
Leetcode|二叉树的属性|257. 二叉树的所有路径
这块其实要多维护一个记录每个节点下累计路径的队列,该队列和数的广度优先队列同步进出数据,当遇到叶节点时,原路径向量把当前叶节点对应的累计路径进行存储即可。
SL_World
2021/09/18
2430
二叉树面试题-你已经是棵成熟的二叉树了,要学会自己解题
如果一棵树只有一个节点,那么它的深度是1.如果根节点只有左子树,那深度是其左子树的深度+1,同样的只有右子树的话,深度是其右子树深度+1,如果既有左子树又有右子树,取两个子树的深度最大值+1即可。用递归很容易实现。
唔仄lo咚锵
2022/05/08
2770
二叉树面试题-你已经是棵成熟的二叉树了,要学会自己解题
Leetcode|二叉树的属性|101. 对称二叉树
1 分治法-递归 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(null
SL_World
2021/09/18
1870
数据结构和算法面试题:实现一个函数,将一棵二叉树转换为它的镜像。(递归或者非递归实现)
下面是使用C++实现将一棵二叉树转换为它的镜像(非递归实现)的代码,并附带详细注释:
GeekLiHua
2025/01/21
550
由浅入深二叉树刷题指南与讲解
上一篇我们已经了解了二叉树的实现方式, 那么本篇重在进入二叉树OJ刷题环节, 我也会分享我在写题的思路, 帮助我们更好的理解二叉树, 并且本篇也进行二叉树其他方法的实现, 也欢迎不同观点评论区留言.
用户11317877
2024/10/16
880
由浅入深二叉树刷题指南与讲解
算法:树
在之前的内容中我们学习了链表的这一基础数据结构,单链表是其中的一种,结构形式如下所示:
用户3578099
2022/03/15
7370
算法:树
二叉树问题(三)-LeetCode 669、951、662、199、538、236(中序,层次遍历)
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
算法工程师之路
2019/12/24
6350
2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分
2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。
福大大架构师每日一题
2023/06/06
1990
【LeetCode-二叉树训练】
思路:通过root与其两个子节点判断是否相等,为了通过这个步骤遍历树的所有节点,采用递归方式去遍历即可
每天都要进步呀
2023/03/28
1720
【LeetCode-二叉树训练】
【二叉树OJ】常见面试题
如何判断单值二叉树树,当且仅当当前节点的左子树和右子树的值都等于当前节点的值。然后根据等值的传递性,所有的树就会相等。 为此我们可以运用深度优先遍历的算法,判断当前节点的左右子树的值是否与当前节点相等(注意判断左右子树是否存在),不相等就返回false,相等的话就进行进入二叉树的下一层继续判断,直到最后将结果返回。
Yui_
2024/10/16
420
【二叉树OJ】常见面试题
二叉树问题(二)-LeetCode 965、563、993、958、919(树深度,层次遍历)
如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回 true;否则返回 false。
算法工程师之路
2019/12/24
3600
二叉树-LeetCode 235、236、226、230(中序,LCA,DFS)
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
算法工程师之路
2019/11/26
4960
推荐阅读
2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表 如果在二叉树中,存在一条一直向下的路径 且每个点的数值恰好一一对应
4370
LeetCode 431. 将 N 叉树编码为二叉树(递归/层序)
7410
2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个从 1 到 n 且互不相同的值 另给你一个长度为 m
3480
[数据结构]二叉树OJ(leetcode)
2300
【代码随想录】二刷-二叉树
8460
2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中
2200
DFS基础问题-LeetCode 98、101(二叉树中序遍历,层次遍历)
8060
【数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
1020
Leetcode|二叉树的属性|257. 二叉树的所有路径
2430
二叉树面试题-你已经是棵成熟的二叉树了,要学会自己解题
2770
Leetcode|二叉树的属性|101. 对称二叉树
1870
数据结构和算法面试题:实现一个函数,将一棵二叉树转换为它的镜像。(递归或者非递归实现)
550
由浅入深二叉树刷题指南与讲解
880
算法:树
7370
二叉树问题(三)-LeetCode 669、951、662、199、538、236(中序,层次遍历)
6350
2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分
1990
【LeetCode-二叉树训练】
1720
【二叉树OJ】常见面试题
420
二叉树问题(二)-LeetCode 965、563、993、958、919(树深度,层次遍历)
3600
二叉树-LeetCode 235、236、226、230(中序,LCA,DFS)
4960
相关推荐
2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表 如果在二叉树中,存在一条一直向下的路径 且每个点的数值恰好一一对应
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验