力扣第654题 最大二叉树 c++注释版

news2024/9/22 1:15:40

题目

654. 最大二叉树

中等

相关标签

栈 树 数组 分治 二叉树 单调栈 

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

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

返回 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 中的所有整数 互不相同

思路和解题方法

       首先,创建一个初始化值为0的根节点node

然后,判断给定数组nums的大小,如果数组只有一个元素,则将该元素作为根节点的值,并返回该节点。

接下来,定义变量maxvalmaxvalindex,分别用于记录数组中的最大值和它在数组中的索引。

通过遍历数组,找到最大值和对应的索引。

根据最大值创建一个新的根节点,并赋值给node

然后,根据最大值的索引,将数组切割成两部分:左半部分是最大值左边的元素,右半部分是最大值右边的元素。

对左半部分递归调用constructMaximumBinaryTree函数构建左子树,并将返回的结果赋值给根节点的左子节点。

对右半部分递归调用constructMaximumBinaryTree函数构建右子树,并将返回的结果赋值给根节点的右子节点。

最后,返回根节点node

复杂度

        时间复杂度:

                O(n)

时间复杂度:O(n),其中 n 是数组 nums的长度。单调栈求解左右边界和构造树均需要 O(n)的时间。

        空间复杂度

                O(n)

空间复杂度:O(n),即为单调栈和数组 tree需要使用的空间。

c++ 代码

class Solution { // 定义一个名为Solution的类
public: // 类内部的公共成员开始

    // 定义一个方法 constructMaximumBinaryTree,该方法接受一个整数向量 nums 作为输入
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) { 
        // 创建一个默认的TreeNode对象,值为0,并命名为node
        TreeNode *node = new TreeNode(0); 
        // 如果nums只有一个元素,直接将该元素赋值给node的val,并返回node
        if(nums.size() == 1) {
            node->val = nums[0];
            return node; 
        }
        // 初始化最大值为0,以及最大值所在的索引为0
        int maxval = 0;
        int maxvalindex = 0;
        // 遍历整个nums数组,找到最大的值以及其索引
        for(int i=0;i<nums.size();i++) {
            if(nums[i]>maxval) {
                maxval = nums[i];
                maxvalindex = i;
            } 
        }
        // 创建一个新的TreeNode对象,值最大值maxval,并赋值给node
        node = new TreeNode(maxval);
        // 如果最大值的索引大于0,说明最大值不是数组的第一个元素,那么在左子树中应包含到最大值索引位置的元素
        if(maxvalindex>0) {
            vector<int> newvec(nums.begin(),nums.begin() +maxvalindex); // 创建新的向量,包含原数组的从头到最大值索引位置的元素
            node->left = constructMaximumBinaryTree(newvec); // 递归构造左子树,将返回的节点赋值给node的左子节点
        }
        // 如果最大值的索引小于数组长度减1,说明最大值不是数组的最后一个元素,那么在右子树中应包含从最大值索引位置到数组末尾的元素
        if(maxvalindex<nums.size()-1) {
            vector<int> newvec(nums.begin()+maxvalindex+1,nums.end()); // 创建新的向量,包含原数组从最大值索引位置到末尾的元素
            node->right = constructMaximumBinaryTree(newvec); // 递归构造右子树,将返回的节点赋值给node的右子节点
        }
        // 返回构造好的二叉树的根节点node
        return node;
    }
};

c++优化后的代码

class Solution { // 定义一个类名为Solution。
private: // 这个类的私有部分的开始。
    // 在左闭右开区间[left, right),构造二叉树
    TreeNode* traversal(vector<int>& nums, int left, int right) { // 定义一个私有方法traversal,它接收一个整数向量nums(通过引用传递,以便在函数内部修改原数组)和两个整数left和right作为参数。它返回一个指向TreeNode的指针。
        if (left >= right) return nullptr; // 如果left大于或等于right,则返回空指针,因为这意味着区间内没有元素来构造二叉树。

        // 分割点下标:maxValueIndex
        int maxValueIndex = left; // 初始化maxValueIndex为left,因为left是当前子数组的起始索引,还没有被检查过。
        for (int i = left + 1; i < right; ++i) { // 从left+1开始遍历到right-1。
            if (nums[i] > nums[maxValueIndex]) maxValueIndex = i; // 如果当前元素大于maxValueIndex所在位置的元素,则更新maxValueIndex。
        }

        TreeNode* root = new TreeNode(nums[maxValueIndex]); // 创建一个新的TreeNode对象,其值是nums中最大值,并把它赋值给root。

        // 左闭右开:[left, maxValueIndex)
        root->left = traversal(nums, left, maxValueIndex); // 对左半部分递归调用traversal方法并把返回的树节点赋值给root的左子节点。

        // 左闭右开:[maxValueIndex + 1, right)
        root->right = traversal(nums, maxValueIndex + 1, right); // 对右半部分递归调用traversal方法并把返回的树节点赋值给root的右子节点。

        return root; // 返回构造好的二叉树的根节点。
    }
public: // 这个类的公共部分的开始。
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) { // 定义一个公共方法constructMaximumBinaryTree,它接收一个整数向量nums(通过引用传递,以便在函数内部修改原数组)并返回一个指向TreeNode的指针。
        return traversal(nums, 0, nums.size()); // 对整个数组调用traversal方法并返回结果。
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

曦力音视频转换工具Xilisoft Video Converter Ultimate mac中文版

Xilisoft Video Converter Ultimate mac是一款功能强大的视频转换软件&#xff0c;它可以将几乎所有流行的视频格式转换为其他格式&#xff0c;包括AVI、MPEG、WMV、DivX、MP4、H.264/AVC、AVCHD、MKV、RM、MOV、XviD、3GP等。此外&#xff0c;它还支持将视频转换为音频格式&am…

小谈设计模式(24)—命令模式

小谈设计模式&#xff08;24&#xff09;—命令模式 专栏介绍专栏地址专栏介绍 命令模式角色分析命令&#xff08;Command&#xff09;具体命令&#xff08;ConcreteCommand&#xff09;接收者&#xff08;Receiver&#xff09;调用者&#xff08;Invoker&#xff09;客户端&am…

遗传算法入门笔记

目录 一、大体实现过程 二、开始我们的进化(具体实现细节) 2.1 先从编码说起 2.1.1 二进制编码法 2.1.&#xff12; 浮点编码法 2.1.3 符号编码法 2.2 为我们的袋鼠染色体编码 2.3 评价个体的适应度 2.4 射杀一些袋鼠 2.5 遗传--染色体交叉(crossover) 2.6 变异--基…

万万没想到,我用文心一言开发了一个儿童小玩具

最近关注到一年一度的百度世界大会今年将于10月17日在北京首钢园举办&#xff0c;本期大会的主题是“生成未来&#xff08;PROMPT THE WORLD&#xff09;”。会上&#xff0c;李彦宏会做主题为「手把手教你做AI原生应用」的演讲&#xff0c;比较期待 Robin 会怎么展示。据说&am…

【后端】韩顺平Java学习笔记(入门篇)

目前准备学后端&#xff0c;java虽然大二上学了但是基本忘没了orz 争取大三卷一点啊啊啊 九月份写的10月份才发orz 中间摆烂了很久&#xff0c;现在目标清晰准备行动了kkk 来源&#xff1a;韩顺平 零基础30天学会Java 目录 I. 简介 一、特点 ✿ 跨平台性 → 运行机制…

GIN框架路由的实现原理

文章目录 首先回顾一下gin框架的路由如何使用的从源码分析一下gin框架gin的路由实现前缀树前缀树的实现压缩前缀树--Radix TrieTrie VS Map 首先回顾一下gin框架的路由如何使用的 package mainimport ("fmt""github.com/gin-gonic/gin""net/http&quo…

使用策略模式重构审批

之前在公司与同时合作开发了一个考核系统&#xff0c;最后干完后整个代码也是合在了我这里&#xff0c;于是进行了codereview&#xff0c;进行优化代码&#xff0c;在审核这边&#xff0c;我先是拆分了公共代码&#xff0c;然后对重复的代码块进行了封装&#xff0c;但是审核这…

Flutter配置Android SDK路径

在使用VSCode作为开发Flutter的工具时&#xff0c;当选择调试设备时&#xff0c;通常看不到android的模拟器&#xff0c;只能看到Chrome之类的。 原因就是Flutter找不到Android的SDK路径&#xff0c;所以无法识别模拟器&#xff0c;我们用flutter doctor命令检查环境时&#xf…

论文《Link Prediction on Latent Heterogeneous Graphs》阅读

论文《Link Prediction on Latent Heterogeneous Graphs》阅读 论文概况IntroductionLHGNNA.语义嵌入a.节点级语义嵌入b.路径级语义嵌入 B.潜在异构上下文聚合a.上下文个性化b.上下文聚合 C.链路预测a.链路编码器b.损失函数 总结 论文概况 本文是2023年WWW上的一篇论文&#xf…

LeetCode 59. 螺旋矩阵 II【数组,模拟】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

563. 二叉树的坡度

563. 二叉树的坡度 C代码&#xff1a; int sum;int dfs(struct TreeNode* root) {if (root NULL) {return 0;}int left dfs(root->left);int right dfs(root->right);sum fabs(left - right);return root->val left right; }int findTilt(struct TreeNode* roo…

【HTML5】语义化标签记录

前言 防止一个页面中全部都是div&#xff0c;或者ul li&#xff0c;在html5推出了很多语义化标签 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 常用语义化案例 一般我用的多的是header&#xff0c;main&#xff0c;footer 这些标签不难理解&#x…

G1 GC详解及设置

一、概述 G1 GC&#xff0c;全称Garbage-First Garbage Collector&#xff0c;在JDK1.7中引入了G1 GC&#xff0c;从JAVA 9开始&#xff0c;G1 GC是默认的GC算法。通过-XX:UseG1GC参数来启用。G1收集器是工作在堆内不同分区上的收集器&#xff0c;分区既可以是年轻代也可以是老…

ChatGLM2-6B微调实践-Lora方案

ChatGLM2-6B微调实践-Lora方案 环境部署Lora微调项目部署准备数据集修改训练脚本adapter推理模型合并与量化合并后的模型推理 微调过程中遇到的问题参考&#xff1a; 环境部署 安装Anaconda、CUDA、PyTorch 参考&#xff1a;ChatGLM2-6B微调实践-P-Tuning方案 Lora微调 项目…

基于opencv,卡尺工具

机器视觉尺寸测量项目中&#xff0c;测量工件尺寸中最基本的卡尺工具。 卡尺工具涉及到的最主要任务&#xff1a; 扫描边缘点&#xff0c;亚像素精度 拟合直线 实现了一个小demo&#xff0c;用来获取工件边缘&#xff0c;亚像素精度。 代码链接放下下面 https://download.cs…

饥荒服务器阿里云租用价格表一年和一个月收费报价表

饥荒阿里云服务器多少钱一个月&#xff1f;阿里云服务器价格9元一个月&#xff0c;阿里云轻量应用服务器2核2G3M带宽轻量服务器一年108元&#xff0c;2核4G4M带宽轻量服务器一年297.98元12个月&#xff1b;阿里云ECS云服务器e系列2核2G配置182元一年、2核4G配置365元一年、2核8…

苹果遭遇安全危机,应用商店曝出不良APP,或影响iPhone的销售

据澎湃新闻报道指苹果的App Store被曝出不良APP位居下载榜前列&#xff0c;这对于向来强调APP严格审核的苹果来说是巨大的打击&#xff0c;更影响向来被认为信息安全遥遥领先的名声&#xff0c;对当下正热销的iPhone15或造成打击。 据了解被曝的软件以“学习XX字母”为命名&…

Apache Shiro 漏洞复现

文章目录 Apache Shiro 漏洞复现1. Apache Shiro 1.2.4 反序列化漏洞1.1 漏洞描述1.2 漏洞原理1.3 漏洞复现1.3.1 环境启动 1.4 漏洞利用1.5 修复方案 Apache Shiro 漏洞复现 链接地址&#xff1a;Vulhub - Docker-Compose file for vulnerability environment 1. Apache Shi…

Chrome自动播放限制策略

原文链接&#xff1a;Chrome 自动播放限制策略 Web浏览器正在朝着更严格的自动播放策略发展&#xff0c;以便改善用户体验&#xff0c;最大限度地降低安装广告拦截器的积极性并减少昂贵和/或受限网络上的数据消耗。这些更改旨在为用户提供更大的播放控制权&#xff0c;并使开发…

ThreeJs中场景(scene)、 相机(camera)、渲染器(renderer)等方法类使用

ThreeJs笔记 简介 WebGL&#xff08;Web Graphics Library&#xff0c;Web图形库&#xff09;&#xff0c;是一个JavaScript API&#xff0c;可在任何兼容的Web浏览器中渲染高性能的交互式3D和2D图形&#xff0c;而无需使用插件 。 WebGL通过引入一个与OpenGL ES 2.0非常一致…