LeetCode-654. 最大二叉树【栈 树 数组 分治 二叉树 单调栈】

news2024/9/9 6:10:12

LeetCode-654. 最大二叉树【栈 树 数组 分治 二叉树 单调栈】

  • 题目描述:
  • 解题思路一:递归,这个问题的难点在于如何找到每个子数组的最大值。此处用的是暴力查找最大值,然后递归构建左右子树。
  • 解题思路二:单调栈,显然暴力解法非最优解。可以将任务转化为找出每一个元素左侧和右侧第一个比它大的元素所在的位置。这就是一个经典的单调栈问题了。如果左侧的元素较小,那么该元素就是左侧元素的右子节点;如果右侧的元素较小,那么该元素就是右侧元素的左子节点。细节看代码注释。
  • 解题思路三:0

题目描述:

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

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

示例 1:
在这里插入图片描述
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:

  • [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    • [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
      • 空数组,无子节点。
      • [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
        • 空数组,无子节点。
        • 只有一个元素,所以子节点是一个值为 1 的节点。
    • [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
      • 只有一个元素,所以子节点是一个值为 0 的节点。
      • 空数组,无子节点。

示例 2:
在这里插入图片描述
输入:nums = [3,2,1]
输出:[3,null,2,null,1]

提示:

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

解题思路一:递归,这个问题的难点在于如何找到每个子数组的最大值。此处用的是暴力查找最大值,然后递归构建左右子树。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        def construct(left: int, right: int) -> Optional[TreeNode]:
            if left>right: return None
            best = left
            for i in range(left + 1, right + 1):
                if nums[i] > nums[best]: best = i
            
            root = TreeNode(nums[best])
            root.left = construct(left, best - 1)
            root.right = construct(best + 1, right)
            return root

        return construct(0, len(nums)-1)

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

解题思路二:单调栈,显然暴力解法非最优解。可以将任务转化为找出每一个元素左侧和右侧第一个比它大的元素所在的位置。这就是一个经典的单调栈问题了。如果左侧的元素较小,那么该元素就是左侧元素的右子节点;如果右侧的元素较小,那么该元素就是右侧元素的左子节点。细节看代码注释。

需要参考LeetCode-496. 下一个更大元素 I【栈 数组 哈希表 单调栈】和LeetCode-503. 下一个更大元素 II【栈 数组 单调栈】
关于更多的解释参考官方题解吧。最大二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        n = len(nums)
        stk = []
        left, right = [-1] * n, [-1] * n
        tree = [None] * n

        # 维护左右侧大值
        for i in range(n):
            tree[i] = TreeNode(nums[i])
            while stk and nums[i] > nums[stk[-1]]:
                # 右侧大值在出栈时维护
                right[stk[-1]] = i
                stk.pop()
            if stk: 
                # 左侧大值在出栈后维护
                left[i] = stk[-1]
            stk.append(i)
        
        root = None
        for i in range(n):
            # 如果左右都没有大值,说明是根节点
            if left[i] == right[i] == -1:
                root = tree[i]
            # 如果右侧没有大值,或者左侧大值小于右侧大值,那么该节点是左侧大值的右孩子
            elif right[i] == -1 or (left[i] != -1 and nums[left[i]] < nums[right[i]]):
                tree[left[i]].right = tree[i]
            # 如果右侧的元素较小,那么该元素就是右侧元素的左子节点。
            else:
                tree[right[i]].left = tree[i]
        return root

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

我们还可以把最后构造树的过程放进单调栈求解的步骤中,省去用来存储左右边界的数组。下面的代码理解起来较为困难,同一个节点的左右子树会被多次赋值,读者可以仔细品味其妙处所在。

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> Optional[TreeNode]:
        n = len(nums)
        stk = list()
        tree = [None] * n

        for i in range(n):
            tree[i] = TreeNode(nums[i])
            while stk and nums[i] > nums[stk[-1]]:
                tree[i].left = tree[stk[-1]]
                stk.pop()
            if stk:
                tree[stk[-1]].right = tree[i]
            stk.append(i)
        
        return tree[stk[0]]

细细品味💪 💪 💪

解题思路三:0


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1304718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何实现更有效率的产线各工业设备数据采集?

随着工业物联网的发展&#xff0c;工业设备的智能化水平越来越高&#xff0c;然而设备的通讯受限于不同设备的物理链路、各种不同的协议&#xff0c;因此大多数设备数据不能互联互通。宝贵的数据被白白浪费掉&#xff0c;无法进行统一管理分析&#xff0c;因此亟需解决这一难题…

做数据分析为何要学统计学(9)——什么是回归分析

​回归分析&#xff08;regression analysis)是量化两种或两种以上因素/变量间相互依赖关系的统计分析方法。回归分析根据因素的数量&#xff0c;分为一元回归和多元回归分析&#xff1b;按因素之间依赖关系的复杂程度&#xff0c;可分为线性回归分析和非线性回归分析。我们通过…

【带头学C++】----- 九、类和对象 ---- 9.12 C++之友元函数(9.12.5---9.12.7)

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️创做不易&#xff0c;麻烦点个关注❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ ❤️❤️❤️❤️❤️❤️❤️❤️❤️文末有惊喜&#xff01;献舞一支&#xff01;❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目录 补充上…

软文营销怎么做才能“人性化”,媒介盒子有妙招

软文营销已经成为品牌宣传的重要方式之一&#xff0c;想要做好软文营销&#xff0c;则要避免高高在上的宣传&#xff0c;围绕用户心理&#xff0c;打造人性化的内容。今天媒介盒子就来和大家聊聊软文营销怎么做才能人性化。 一、以情感驱动用户 形成用户印象所需要的时间是1/1…

Netflix Mac(奈飞客户端)激活版软件介绍

Netflix Mac(奈飞客户端)是一款流行的视频播放软件&#xff0c;专为Mac用户设计。它提供了大量的高质量电影、电视剧、纪录片和动画片资源&#xff0c;让用户可以随时随地观看自己喜欢的内容。 首先&#xff0c;Netflix Mac(奈飞客户端)以其简洁直观的用户界面而闻名。用户可以…

用FPGA实现四通道、全频率 GNSS RF 接收器-用于卫星的精确定位

用FPGA实现四通道、全频率 GNSS RF 接收器-用于卫星的精确定位 概念 全球导航卫星系统&#xff08;英文&#xff1a;Global Navigation Satellite System&#xff0c;GNSS &#xff09;&#xff0c;又称全球卫星导航系统&#xff0c;是能在地球表面或近地空间的任何地点为用户提…

阿木实验室普罗米修斯项目环境配置

引言 普罗米修斯项目其实只是个大ROS功能包&#xff0c; 里面每个模块就是每个ROS功能包&#xff0c;比如控制模块&#xff0c;视觉模块等等。对PX4配置的与这个一样&#xff0c;另外他是使用自己的P系列无人机&#xff08;我个人是&#xff30;450&#xff09;&#xff0c;所…

LAMP的搭建

LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词&#xff0c;具体包括Linux操作系统、Apache网站服务器、MySQL数据库服务器、PHP&#xff08;或…

[学习笔记]在CentOS7中用Docker方式安装Jenkins

文章目录 原理&#xff1a;创建Docker网桥网络安装DinD创建镜像构建镜像运行容器 原理&#xff1a; Docker in Docker &#xff08;以下简称 DinD&#xff09;可以在 Container 中直接运行一个 Docker Daemon &#xff0c;然后使用 Container 中的 Docker CLI 工具操作容器。其…

做数据分析为何要学统计学(6)——什么问题适合使用t检验?

t检验&#xff08;Students t test&#xff09;&#xff0c;主要依靠总体正态分布的小样本&#xff08;例如n < 30&#xff09;对总体均值水平进行差异性判断。 t检验要求样本不能超过两组&#xff0c;且每组样本总体服从正态分布&#xff08;对于三组以上样本的&#xff0…

apt-get update失败

一、先验证是否有网络 rootlocalhost:~# ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution rootlocalhost:~# 说明没有网&#xff0c;参考&#xff1a;https://blog.csdn.net/qq_43445867/article/details/132384031 sudo vim /etc/resolv.con…

windows如何解决端口冲突(实用篇)

在项目设计中&#xff0c;环境配置成功点击运行瞬间&#xff0c;一大堆红爆出&#xff0c;8080端口占用&#xff0c;这个是很烦人的。。。 解决方式&#xff1a; 笨方法&#xff1a;一、查看所有端口实用情况&#xff08;挨个扫&#xff09; 按住【WINR】快捷键打开运行输入…

报表控件FastReport .NET v2024功能演示—更改图图片形状

报表生成器FastReport .NET 是适用于.NET Core 3&#xff0c;ASP.NET&#xff0c;MVC和Windows窗体的全功能报告库。使用FastReport .NET&#xff0c;您可以创建独立于应用程序的.NET报告。 FastReport .net下载&#xff08;qun&#xff1a;585577353&#xff09;https://www.e…

靠着这份280页的前端面试指南,拿下了字节跳动offer

笔者是在今年秋招面试的头条教育线&#xff0c;顺利拿到了offer&#xff0c;把还记得的东西写下来&#xff0c;供大家参考一下。 一面 tcp 和 udp 的区别和使用场景&#xff1f;quic 基于 udp 怎么保证可靠性&#xff1f;讲一下同源策略和跨域方案&#xff1f;CORS 的几个头部…

AutoAnimate动画库,仅需一行代码

插件官网,支持react,vue AutoAnimate - Add motion to your apps with a single line of code 自动加动画原理 AutoAnimate 加动画的原理也很简单&#xff0c;监听绑定的 DOM 节点里 DOM 结构变化&#xff0c;自动添加对应的过渡动画&#xff1a; 增加子节点 > 渐入动画…

智能检测/摄像头监控系统EasyCVR无法启动进程是什么原因?如何解决?

国标GB28181智慧安防平台EasyCVR支持高清视频的接入和传输、分发&#xff0c;平台采用了开放式的网络结构&#xff0c;提供实时远程视频监控、录像回放与存储等功能。视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支持…

数据库系统 --- 关系模型

一、关系模型的数据结构以及形式化定义 1.关系 域&#xff1a;一组具有相同数据结构的值的集合。 笛卡尔积&#xff1a;域上的一种集合运算。多个集合做笛卡尔积的结果是每个集合取一个元素组合得到的一个新的集合。 域的基数&#xff1a;一个域上允许的不同取值的个数。 关系&…

【数仓理论】

一、数仓建模方法论 1.1 ER模型&#xff08;Entity Relationship、实体关系模型、范式模型&#xff09; ER模型是Bill Inmon提出的一种建模方法&#xff0c;实体关系模型将复杂的数据抽象为两个概念 ---- 实体和关系 该模型在范式理论上符合3NF&#xff0c;这种模型目的是减少…

VTK学习(入门级教程,包括安装和使用)~持续更新中

说明&#xff1a;研究QTVTK有段时间了&#xff0c;准备把学到的东西分享给大家&#xff0c;这篇博客以VSQTVTK为主进行展开学习的。 VTK学习 VTK安装和使用教程VTK入门级教程设计界面vtkStudy.ui的操作vtkStudy.h头文件说明完整代码 vtkStudy.cpp绘制球体绘制长方体绘制圆柱绘制…

wordpress多語言插件Polylang與GTranslate會有衝突

wordpress多語言插件Polylang與GTranslate會有衝突,會導致分頁顯示不完整&#xff0c;需要禁用或卸載其中一個 分頁顯示才會沒問題 GTranslate必須要先按一種語言編輯好你要發佈網站&#xff0c;GTranslate這種語言為基礎去翻譯出來&#xff0c;其實內裡是套用了google 翻譯的…