【LeetCode】654. 最大二叉树

111 阅读2分钟

image.png

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

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

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

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    QfMLXjd59T.png

  • 题目解析

    • 1 <= nums.length <= 1000
    • 0 <= nums[i] <= 1000
    • nums 中的所有整数 互不相同

二、思路分析:

我们拿到本题,读取题目又是一道关于二叉树的题,要求我们对nums列表中元素按最大值方式进行取值,构造一个二叉树。那最大值怎么取法,我们继续审题:

  • 首先每次nums的最大值,构建一个root根节点
  • 最大值的左边数组元素中最大值,来构建root的左子树
  • 最大值的右边数组元素中最大值,来构建root的右子树
  • 以此类推,直到nums为空为主,退出递归

因此根据题目,我们可以直接根据递归方法来进行解答即可,思路如下:

  • 构建二叉树每一个节点都查找nums数组中指定区域找到最大值,然后构建TreeNode
  • 因此在递归中,递归的结束条件是数组nums为空
  • maxnum 可以使用max(nums)求出,再使用nums.index(maxnum)求出其索引位置maxindex
  • root的左节点的值是取maxindex左边的元素,因此leftnums取值范围为nums[:maxindex]
  • root的右节点的值是取maxindex右边的元素,因此rightnums取值范围为nums[maxindex+1:]
  • 构建root节点,值为maxnum,left节点为self.constructMaximumBinaryTree(leftnums),right节点为self.constructMaxmumBinaryTree(rightnums)
  • 根据以上递归思路,结合案例1,手动画图如图所示: image.png 根据以上思路,我们可以结合python相关的方法实现,代码如下所示:
    class Solution(object):
        def constructMaximumBinaryTree(self, nums):
            """
            :type nums: List[int]
            :rtype: TreeNode
            """
            if not nums:
                return
            maxnum = max(nums)
            maxindex = nums.index(maxnum)
            rightnums = nums[maxindex+1:]
            leftnums = nums[:maxindex]
            root = TreeNode(maxnum,self.constructMaximumBinaryTree(leftnums),self.constructMaximumBinaryTree(rightnums))
            return root
    

但是上述虽然说,实现题目内容,但是关于一些细节点,我们直接使用Python内部方法实现的,不利于我们对其过程的掌握的。学习完大佬写的代码,我们将上述代码进行优化:

  • 找出nums最大值:max(nums)->使用双指针实现,找到最大值索引i,最大值为nums[i]
    # maxnum = max(nums)
    # maxindex = nums.index(maxnum)
    left,right = 0,len(nums)
    maxindex = left
    for i in range(left,right):
        if nums[i] > nums[maxindex]:
             maxindex = i
    maxnum = nums[i]
    
  • 重新定义以左右索引为参数的construct递归函数,递归退出条件 left >= right
    def construct(left,right):
            if left >= right: return None
            maxindex = left
            for i in range(left+1,right):
                if nums[i] > nums[maxindex]:
                    maxindex = i
            root = TreeNode(nums[maxindex])
            root.left = construct(left,maxindex)
            root.right = construct(maxindex+1,right)
            return root
    
  • 方法二:单调栈法

  • 在上述递归中,时间耗时比较长。在数据量大的时候,递归方法优势不是很明显啦
  • 我们观察一下二叉树构建过程,发现在当前节点root的值val进行比较
  • 当num > root.val值时,则创建num为根节点,num.left左子树上连接前面的节点
  • 当num < root.val值时,则在root.right右子树上构建TreeNode
  • 因此在本题上,我们可以使用数组模拟栈的方法来构建二叉树,思路如下:
    • 首先定义一个stk栈,存储构建的TreeNode的cur
    • 使用for循环遍历nums,每取一个num并创建以num的TreeNode节点
    • 当stk为空时,则将TreeNode(num)节点存储在stk列表中
    • 当num < stk[-1].val时,则将stk栈顶部节点.right赋值为cur
    • 当num > str[-1].val时,则循环从顶部将stk栈节点推出,并添加到cur.left节点上
    • 直到遍历完整个nums列表,然后返回stk[0]树
    class Solution(object):
    def constructMaximumBinaryTree(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        stk = list()
        for num in nums:
            cur = TreeNode(num)
            while stk and stk[-1].val < num:
                cur.left = stk.pop()
            if stk:
                stk[-1].right = cur
            stk.append(cur)
        return stk[0]
    
    

三、总结:

本题是一道关于构建二叉树的题目,按照每一个节点满足root.val大于root.letf.val和root.right.val值,当新节点num大于root.val值时,则以新节点num为root节点,root则作为左子树存在,递归方法较于单调栈来说比较低效。本题使用递归方法提交,AC 提交记录如下: image.png

  • 时间复杂度:O(n^2),n为nums数组的长度
  • 空间复杂度:O(n),即为最坏情况下需要使用的栈空间

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