LeetCode108. 将有序数组转换为二叉搜索树

108. 将有序数组转换为二叉搜索树

一、题目

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

img

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

img

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums严格递增 顺序排列

二、题解

方法一:递归

我们知道平衡二叉搜索树的特点是每个节点的左子树和右子树的高度差不超过1,因此我们尽可能要让节点两端的元素个数相近。

算法思路:

  1. 首先,我们要找到一个合适的根节点。由于给定的数组是有序的,我们可以选择中间位置的元素作为根节点,这样可以保证左右子树的元素数量相差不大,从而有助于维持平衡性质。

  2. 在选择了根节点之后,我们将数组分成两部分:左子数组和右子数组。左子数组中的元素都小于根节点,右子数组中的元素都大于根节点。

  3. 然后,我们递归地对左子数组和右子数组进行相同的操作,分别构建左子树和右子树。这样就能保证左右子树的高度差不超过1。

  4. 最后,将根节点与构建好的左右子树连接起来,形成一棵完整的平衡二叉搜索树。

具体实现:

class Solution {
public:TreeNode* sortedArrayToBST(vector<int>& nums) {if(nums.size() == 0) return nullptr; // 空数组直接返回空指针(终止条件)int size = nums.size();int middle = size/2; // 找到中间位置的索引TreeNode *root = new TreeNode(nums[middle]); // 创建根节点vector<int> vecL(nums.begin(),nums.begin()+middle); // 左子数组vector<int> vecR(nums.begin()+middle+1, nums.end()); // 右子数组root->left = sortedArrayToBST(vecL); // 递归构建左子树root->right = sortedArrayToBST(vecR); // 递归构建右子树return root; // 返回根节点}
};

算法分析:

  • 时间复杂度:每个元素都会被遍历一次,因此总的时间复杂度为 O(n),其中 n 是数组中的元素数量。
  • 空间复杂度:每次递归都会创建新的左右子数组,因此递归的最大深度是 log(n),每层需要的空间为 O(n),所以总的空间复杂度为 O(nlogn)。
方法二:迭代

以下是代码的思路:

  1. 首先,检查给定的有序数组是否为空,如果为空,则直接返回空指针,表示空树。

  2. 创建一个根节点 root,暂时将其值设为0,作为占位值。然后创建三个队列:nodeQue 用于存储待处理的节点,leftQue 用于存储每个节点对应的左区间下标,rightQue 用于存储每个节点对应的右区间下标。

  3. 将根节点 root、左区间下标0和右区间下标 nums.size() - 1 分别入队列。

  4. 进入迭代循环,从队列中取出一个待处理的节点 curNode,同时获取它对应的左区间下标 left 和右区间下标 right,计算当前区间的中间位置 mid

  5. 将中间位置 mid 对应的元素值赋给当前节点 curNode->val,此时树的结构仍未构建。

  6. 如果左区间 left 小于等于 mid - 1,则创建左子节点,并将其入队列。更新 leftQuerightQue 分别为 leftmid - 1

  7. 如果右区间 right 大于等于 mid + 1,则创建右子节点,并将其入队列。更新 leftQuemid + 1,并维持 rightQue 不变。

  8. 重复以上步骤,直到队列为空,此时所有的节点都已经处理完毕,构建的二叉搜索树也完成。

  9. 返回根节点 root,即完成了整个构建过程。

class Solution {
public:TreeNode* sortedArrayToBST(vector<int>& nums) {if (nums.empty()) {return nullptr;}TreeNode* root = new TreeNode(0);   // 初始根节点,暂时使用0作为占位值queue<TreeNode*> nodeQue;           // 存储待处理的节点queue<int> leftQue;                 // 存储当前节点对应的左区间下标queue<int> rightQue;                // 存储当前节点对应的右区间下标nodeQue.push(root);                 // 根节点入队列leftQue.push(0);                    // 0为初始左区间下标rightQue.push(nums.size() - 1);     // nums.size() - 1为初始右区间下标while (!nodeQue.empty()) {TreeNode* curNode = nodeQue.front(); nodeQue.pop();// 当前待处理节点int left = leftQue.front(); leftQue.pop();    // 当前节点对应的左区间下标int right = rightQue.front(); rightQue.pop(); // 当前节点对应的右区间下标int mid = left + (right - left) / 2;  // 计算当前区间的中间位置curNode->val = nums[mid];   // 将中间位置元素赋值给当前节点,此时树的结构仍未构建if (left <= mid - 1) {  // 如果左区间仍有元素可用,创建左子节点curNode->left = new TreeNode(0);  nodeQue.push(curNode->left);  // 将左子节点加入待处理队列leftQue.push(left);   // 更新左区间下标rightQue.push(mid - 1); // 更新右区间下标}if (right >= mid + 1) { // 如果右区间仍有元素可用,创建右子节点curNode->right = new TreeNode(0); nodeQue.push(curNode->right); // 将右子节点加入待处理队列leftQue.push(mid + 1); // 更新左区间下标rightQue.push(right);  // 更新右区间下标}}return root; }
};

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF怎么批量加密?掌握这招事半功倍

PDF文件是一种广泛使用的文档格式&#xff0c;而加密可以有效地保护PDF文件的安全性。当需要批量加密PDF文件时&#xff0c;以下是一些方法及注意事项。 PDF批量加密的方法 相信很多小伙伴平时都是直接在PDF阅读器中对文档进行加密&#xff0c;但是这样只能每次对当前打开的文…

Android JNI系列详解之CMake编译工具的使用

一、CMake工具的介绍 如图所示&#xff0c;CMake工具的主要作用是&#xff0c;将C/C编写的native源文件编译打包生成库文件&#xff08;包含动态库或者静态库文件&#xff09;&#xff0c;集成到Android中使用。 二、CMake编译工具的使用 使用主要是配置两个文件&#xff1a;CM…

0103水平分片-jdbc-shardingsphere-中间件

文章目录 1 准备服务器1.1 创建server-order0容器1.2 创建server-order1容器 2、基本水平分片2.1、基本配置2.2、数据源配置2.3、标椎分片表配置2.4、行表达式2.5、分片算法配置2.6、分布式序列算法 3、多表关联3.1、创建关联表3.2、创建实体类3.3、创建Mapper3.4、配置关联表3…

Python土力学与基础工程计算.PDF-压水试验

Python 求解代码如下&#xff1a; 1. import math 2. 3. # 输入参数 4. L 2.0 # 试验段长度&#xff0c;m 5. Q 120.0 # 第三阶段计算流量&#xff0c;L/min 6. p 1.5 # 第三阶段试验段压力&#xff0c;MPa 7. r0 0.05 # 钻孔半径&#xff0c;m 8. 9. # 计算透…

kafka--技术文档--spring-boot集成基础简单使用

阿丹&#xff1a; 查阅了很多资料了解到&#xff0c;使用了spring-boot中整合的kafka的使用是被封装好的。也就是说这些使用其实和在linux中的使用kafka代码的使用其实没有太大关系。但是逻辑是一样的。这点要注意&#xff01; 使用spring-boot整合kafka 1、导入依赖 核心配…

如何安装指定版本node.js,安装旧版本node

1、查看当前是否安装node&#xff0c;如果安装了需要先卸载当前版本node 搜索控制面板 -> 找到程序/卸载程序 -> 在里面找到node -> 然后右击卸载 2、卸载完成后就要安装其他版本得node.js 找到想要安装的对应版本&#xff0c;安装.msi格式的安装包 注&#xff…

权重初始化

常用的权重初始化方法&#xff1a; 随机初始化&#xff08;Random Initialization&#xff09; Xavier 初始化&#xff08;Glorot Initialization&#xff09; He 初始化&#xff08;He Initialization&#xff09;Kaiming 零初始化&#xff08;Zero Initialization&#x…

【C语言】文件操作 -- 详解

一、什么是文件 磁盘上的文件是文件。 1、为什么要使用文件 举个例子&#xff0c;当我们想实现一个 “通讯录” 程序时&#xff0c;在通讯录中新建联系人、删除联系人等一系列操作&#xff0c;此时的数据存储于内存中&#xff0c;程序退出后所有数据都会随之消失。为了让通讯录…

【TPC开证报错】-出库单数据无法匹配【成品产出单明细】

今天可信平台有个证书无法开证&#xff0c;送审报错。 其实业务逻辑是销售出库的单据&#xff0c;也会有个成品入库单。 成品入库单里面的所有箱码&#xff0c;都需要包装记录。 这个就是MES系统里的包装报工&#xff08;之前自动化缺失的包装数据&#xff0c;曾经导过一次。…

Spark第三课

1.分区规则 1.分区规则 shuffle 1.打乱顺序 2.重新组合 1.分区的规则 默认与MapReduce的规则一致,都是按照哈希值取余进行分配. 一个分区可以多个组,一个组的数据必须一个分区 2. 分组的分区导致数据倾斜怎么解决? 扩容 让分区变多修改分区规则 3.HashMap扩容为什么必须…

2023年Java核心技术面试第七篇(篇篇万字精讲)

目录 十二 . Java 提供了哪些IO方式&#xff1f;NIO如何实现多路复用&#xff1f; 12.1 典型回答&#xff1a; 12.1.1 传统的java.io包&#xff1a; 12.1.2 Java 1.4中引入NIO&#xff08;java.nio包&#xff09;&#xff1a; 12.1.2 .1 详细解释&#xff1a; 12.1.2.2 多路复…

抖音seo短视频矩阵系统源代码开发原型--开源

一、系统设计 1.需求分析 抖音SEO矩阵系统的主要功能是提高视频的曝光和排名&#xff0c;因此&#xff0c;其主要需求包括&#xff1a; 1&#xff09;关键词研究&#xff1a;通过分析用户搜索行为&#xff0c;挖掘出热门关键词&#xff0c;以便制定针对性的SEO策略。 2&…

无涯教程-PHP - IntlChar类

在PHP7中&#xff0c;添加了一个新的 IntlChar 类&#xff0c;该类试图公开其他ICU函数。此类定义了许多静态方法和常量&#xff0c;可用于操作unicode字符。使用此类之前&#xff0c;您需要先安装 Intl 扩展名。 <?phpprintf(%x, IntlChar::CODEPOINT_MAX);print (IntlCh…

java:Tomcat

文章目录 背景服务器web 服务器服务资源的分类服务器软件的分类nginx 和 tomact总结 安装Tomcatbrew安装官网压缩包安装IDEA集成IDEA插件 说明 背景 在讲 Tomcat 是啥之前&#xff0c;我们先来了解一些概念。 服务器 可以理解为一个高性能的电脑&#xff0c;但是这个电脑现在…

数据湖:解锁数据价值的新时代

文章首发地址 数据湖&#xff08;Data Lake&#xff09;是一种数据存储和管理架构&#xff0c;它将不同类型的数据&#xff08;如结构化数据、半结构化数据和非结构化数据&#xff09;以原始形式保存在一个公共存储库中&#xff0c;而不强制执行预定义模式或数据结构。数据湖…

下半场开哨!AIGC+智能汽车,谁在引领市场新风口

“智能汽车已经成为AIGC应用的下一个‘重地’。” 中科创达副总裁、畅行智驾CEO屠科在8月22日于南京举办的《软件赋能汽车智能化转型发展高峰论坛》上发表演讲时表示&#xff1a;在AIGC时代&#xff0c;汽车的“智能属性”将加速释放&#xff0c;智能驾驶也将迎来快速发展。 中…

Smartbi电子表格软件版本更新,首次推出Excel轻应用和语音播放

Smartbi电子表格软件又又又更新啦&#xff01; 此次更新&#xff0c;首次推出了新特性——Excel轻应用和语音播报。另外&#xff0c;还对产品功能、Demo示例、配套文档进行了完善和迭代。 低代码开发Excel轻应用 可实现迅速发布web应用 业务用户的需求往往都处于“解决问题”…

第4篇:vscode+platformio搭建esp32 arduino开发环境

第1篇:Arduino与ESP32开发板的安装方法 第2篇:ESP32 helloword第一个程序示范点亮板载LED 第3篇:vscode搭建esp32 arduino开发环境 1.配置默认安装路径&#xff0c;安装到D盘。 打开环境变量&#xff0c;点击新建 输入变量名PLATFORMIO_CORE_DIR与路径&#xff1a;D:\PLATF…

ModaHub魔搭社区:WinPlan垂直大模型数据采集

WinPlan经营大脑数据手动提交 数据采集模版创建后,用户可手动提交数据 数据批量导入 1、第一步:上传Excel 如何选择Excel本系统的批量导入支持选择任意相关的Excel,映射到数据采集模版的各列,即可实现批量导入;相关Excel可以是自行维护的相关数据、或从其他业务系统导出…