• [二叉树&单调栈/递归] LeetCode 654. 最大二叉树(笛卡尔树)


    LeetCode 654. 最大二叉树

    给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

    • 创建一个根节点,其值为 nums 中的最大值。
    • 递归地在最大值 左边子数组前缀上 构建左子树。
    • 递归地在最大值 右边子数组后缀上 构建右子树。

    返回 nums 构建的 最大二叉树 。

    链接:https://leetcode.cn/problems/maximum-binary-tree

    示例:
    输入:nums = [3,2,1,6,0,5]
    输出:
    在这里插入图片描述
    这样子形式的树其实就是 笛卡尔树

    笛卡尔树有如下性质:

    1. 中序遍历可以得到原来的数组
    2. 每个节点的左右子树是在自己区间内距离自己最近的左右最大值

    Solution

    递归

    模拟递归做法,每次在左右区间找到找到最大值以及其索引,并入二叉树。

    时间复杂度: O ( n 2 ) O(n^2) O(n2)
    空间复杂度: O ( 1 ) O(1) O(1)

    class Solution:
        def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
            def dfs(nums: List[int], i: int, j: int) -> Optional[TreeNode]:
                if not nums[i:j]:
                    return None
                v = max(nums[i:j])
                idx = nums.index(v)
                return TreeNode(v, dfs(nums, i, idx), dfs(nums, idx + 1, j))
            return dfs(nums, 0, len(nums))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单调栈

    演示动画
    遍历数组:

    • 若栈不空,并且栈顶元素小于当前元素,重复弹出栈顶元素,并将栈顶元素变成当前元素的左孩子
    • 若栈顶还有元素(该栈顶元素一定比当前元素大),把当前元素变成栈顶元素的右孩子
    • 当前元素入栈

    时间复杂度: O ( n ) O(n) O(n)
    空间复杂度: O ( n ) O(n) O(n)

    class Solution:
        def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
            stack = []
            for x in nums:
                cur = TreeNode(x)
                # 栈不空,且 栈顶元素 < 当前元素, 将栈顶元素变成当前元素的左孩子
                while stack and stack[-1].val < x:
                    cur.left = stack.pop()
                # 如果栈顶还有元素,说明 栈顶元素 > 当前元素,将当前元素变成栈顶元素的右孩子
                if stack:
                    stack[-1].right = cur
                stack.append(cur)
            return stack[0]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    最后得到的栈底元素即为最后的根节点
    中序遍历该树就是原数组。

  • 相关阅读:
    数据结构:(c实现)手把手教你实现栈和队列(内附详细代码)
    cesium 之 flyTo、setView、lookat
    Docker 网络与资源控制
    Banana Pi开源社区开源硬件瑞芯微RK3568/RK3588全国产化支持计划
    centos7安装kubernets集群
    周志华《机器学习》课程系列笔记——目录导航页
    配置logback日志
    关于前端就业前景的一点看法
    oracle安装,导出、导入domp文件、解开oracle行级锁
    JS Promise 之 Hello World
  • 原文地址:https://blog.csdn.net/qq_39906884/article/details/126462402