662. 二叉树最大宽度(BFS+DFS)

272 阅读3分钟

image.jpeg

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    PRb597i9tL.png

  • 题目解析

    • 树中节点的数目范围是 [1, 3000]
    • -100 <= Node.val <= 100

二、思路分析:

我们今天拿到本题是 leetcode 难度为中等题 662. 二叉树最大宽度。根据题目要求对一棵二叉树中求出在所有层中最大的宽度。那么对于null节点是否要计算呢?,继续看题目说明:

  • 最大宽度:二叉树所有层宽度中的最大宽度
  • 每一层宽度计算:最左边到最右边的非空节点之间的长度
  • 二叉树与满二叉树结构一致,两端点之间null的延伸的null子节点也要纳入计算

根据题目内容的介绍,对于二叉树题目解法可以使用典型的广度优先算法和深度优先算法两种方法,思路如下:

  • 方法一:广度优先遍历(BFS)

    • 本题是要求出每一层的宽度,所以使用广度优先遍历方法比较容易
    • 二叉树中每index层的最左边的编号是2index,最右边的编号是2index+1
    • 创建一个初始化的二维数组arr,并将root节点所在层初始化为1数组存入到arr中
    • 使用while循环遍历二叉树的每一层,将每一层的节点arr值赋值给tmp,并清除上一层的节点数据将arr重置为空数组
    • 使用for循环遍历tmp的所有节点node,当node.left存在则将node.left和2*index组合成数组存入到arr中
    • 当node.right存在时,则将node.right和2*index+1组合成数组存入到arr中
    • ans值求tmp数组中tmp[-1][1]与tmp[0][1]差值取最大值
    class Solution(object):
        def widthOfBinaryTree(self, root):
            """
            :type root: TreeNode
            :rtype: int
            """
            ans = 0
            arr = [[root,1]]
            while arr:
                tmp = arr 
                arr = []
                for node,index in tmp:
                    if node.left:
                        arr.append([node.left,index*2])
                    if node.right:
                        arr.append([node.right,index*2+1])
                ans = max(ans,tmp[-1][1]- tmp[0][1]+1)
    
            return ans
    
    
  • 方法二: 深度优先遍历(DFS)

    • 本题的关键之处需要使用list来记录每一层的最小和最大编号,可以使用DFS来前序遍历求得
    • 在前序遍历过程中,当arr的长度小于等于depth时,则初始最大编号和最小编号为level
    • 当list的长度大于depth时,则将arr[level][1]值进行更新
    • 直到root节点为空节点退出
    • 再使用for循环遍历arr列表,将取出最大值并返回
    class Solution(object):
        def widthOfBinaryTree(self, root):
            arr = []
            ans = 0
            def dfs(root,level,depth):
                if not root:return
                if len(arr) <= depth:
                    arr.append([level,level])
                else:
                    arr[depth][1] = level
                dfs(root.left,2*level,depth+1)
                dfs(root.right,2*level+1,depth+1)
    
            dfs(root,1,0)
            for num in arr:
                ans = max(ans,num[1]-num[0]+1)
    
            return ans
    

三、总结:

本题是一道经典的二叉树题,一般解答二叉树类型的都可以使用DFS和BFS两种方法,在本题中需要求出二叉树每一层的宽度,并且找到层数index与左边节点和右边节点关系是2index,和2index+1,可以借助二维数组就可以存储到每一层的最右边和最左边的节点的编号,AC提交记录如下:

image.png

  • 时间复杂度:O(n),n为二叉树节点个数
  • 空间复杂度:O(n),n为二叉树的深度

以上是本期内容,欢迎大佬们点赞评论,下期见~~~