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.mzph.cn/news/52797.shtml

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

相关文章

Linux 网络编程 和 字节序的概念

网络编程概述 不同于之前学习的所有通讯方法&#xff0c;多基于Linux内核实现&#xff0c;只能在同一个系统中不同进程或线程间通讯&#xff0c;Linux的网络编程可以实现真正的多机通讯&#xff01; 两个不相关的终端要实现通讯&#xff0c;必须依赖网络&#xff0c;通过地址…

【C++入门到精通】C++入门 —— 继承(基类、派生类和多态性)

阅读导航 前言一、继承的概念及定义1. 继承的概念2.继承的定义⭕定义格式⭕继承关系和访问限定符⭕继承基类成员访问方式的变化 二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承⭕单…

4.物联网LWIP之C/S编程,stm32作为服务器,stm32作为客户端,代码的优化

LWIP配置 服务器端实现 客户端实现 错误分析 一。LWIP配置&#xff08;FREERTOS配置&#xff0c;ETH配置&#xff0c;LWIP配置&#xff09; 1.FREERTOS配置 为什么要修改定时源为Tim1&#xff1f;不用systick&#xff1f; 原因&#xff1a;HAL库与FREERTOS都需要使用systi…

深度学习入门教学——二分分类

1、什么是二分分类&#xff1f; 二分分类就是判断“有”和“没有”、“是”和“不是”的问题&#xff0c;也就是监督学习中的分类问题。例如&#xff0c;输入一张图片&#xff0c;输出识别该图片的标签。计算机输入图片转化过程如下&#xff1a; 2、神经网络常用符号表示 (x, …

蓝蓝设计UI设计公司-界面设计与开发案例

天津航天中为项目 中国南方电网十二个软件交互优化和界面设计 图标设计 | 交互设计 | 界面设计 天津航天中为数据系统科技有限公司是航天503所控股的专业化公司&#xff0c;坐落于天津滨海新区航天技术产业园&#xff0c;是航天五院家入住天津未来科技城的军民融合型企业&…

Qt文件系统操作和文件的读写

一、文件操作类概述 QIODevice&#xff1a;所有输入输出设备的基础类 QFile&#xff1a;用于文件操作和文件数据读写的类QSaveFile&#xff1a;用于安全保存文件的类QTemporaryFile&#xff1a;用于创建临时文件的类QTcpSocket和QUdpSocket&#xff1a;分别实现了TCP和UDP的类…

解决问题:C++ [某变量名] was not declared in this scope

目录 程序报错的问题 查看程序问题 发现错误代码 错误原因 修改代码 再次运行 程序报错的问题 查看程序问题 发现错误代码 cout<<c; 错误原因 c 这个变量还没有在这个程序中定义 修改代码 加上 int c; 再次运行

使用Dockerfile部署java项目

1、移动java包到创建的目录下 2、编写Dockerfile文件 在同一目录下使用如下命令创建文件 touch Dockerfile 文件内容如下&#xff1a; #依赖的父镜像 FROM java:8 #作者 MAINTAINER maxurui #jar包添加到镜像中 ADD springboot3-0.0.1-SNAPSHOT.jar springboot3-0.0.1-SNAPSHO…

SOPC之NIOS Ⅱ实现电机转速PID控制(调用中断函数)

通过FPGA开发板上的NIOS Ⅱ搭建电机控制的硬件平台&#xff0c;包括电机正反转、编码器的读取&#xff0c;再通过软件部分实现PID算法对电机速度进行控制&#xff0c;使其能够渐近设定的编码器目标值。 一、问题与改进 SOPC之NIOS Ⅱ实现电机转速PID控制_STATEABC的博客-CSDN…

k8s-ingress-context deadline exceeded

报错&#xff1a; rancher-rke-01:~/rke # helm install rancher rancher-latest/rancher --namespace cattle-system --set hostnamewww.rancher.local Error: INSTALLATION FAILED: Internal error occurred: failed calling webhook "validate.nginx.ingress.kube…

C语言刷题训练DAY.13

1.有序序列判断 解题思路&#xff1a; 这里我们先看代码&#xff0c;我们定义了一个flag1和flag2&#xff0c;它的作用主要就是判断是不是升序&#xff0c;具体怎么使用的&#xff0c;我为大家画图展示。 解题代码&#xff1a; #include<stdio.h> int main() {int n 0;…

实验一 ubuntu 网络环境配置

ubuntu 网络环境配置 【实验目的】 掌握 ubuntu 下网络配置的基本方法&#xff0c;能够通过有线网络连通 ubuntu 和开发板 【实验环境】 ubuntu 14.04 发行版FS4412 实验平台 【注意事项】 实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行&#xff0c;以“#”开头的…

改进YOLO系列:6.添加ECA注意力机制

添加ECA注意力机制 1. ECA注意力机制论文2. ECA注意力机制原理3. ECA注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. ECA注意力机制论文 论文题目:ECA-Net: Efficient Channel Attention for Deep Convolutional Neural Networks 论文链接:ECA-N…

[国产MCU]-W801开发实例-按键与GPIO输入

按键与GPIO输入 文章目录 按键与GPIO输入1、硬件准备2、软件准备3、驱动实现4、驱动测试在前面的文章中,我们成功点亮了LED,同时也知道W801的GPIO是可软件配置的。在这里,将详细介绍如何通过按键控制LED。 1、硬件准备 W801开发板一块微动开关一个10K电阻一个导线若干1uF电容…

微服务参数透传实现

说明&#xff1a;在微服务架构中&#xff0c;用户身份经网关验证后&#xff0c;我们可以将用户信息&#xff0c;如ID加入到请求头上。后面的微服务中&#xff0c;可以设置一个拦截器&#xff0c;拦截请求&#xff0c;获取请求头上的用户ID&#xff0c;加入到ThreadLocal中。 最…

深入解析:树结构及其应用

文章目录 学习树的基本概念理解树的遍历方式学习堆和优先队列的应用案例分析&#xff1a;使用堆进行Top K元素的查找结论 &#x1f389;欢迎来到数据结构学习专栏~深入解析&#xff1a;树结构及其应用 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈…

Redis三种持久化方式详解

一、Redis持久性 Redis如何将数据写入磁盘 持久性是指将数据写入持久存储&#xff0c;如固态磁盘&#xff08;SSD&#xff09;。Redis提供了一系列持久性选项。其中包括&#xff1a; RDB&#xff08;快照&#xff09;&#xff1a;RDB持久性以指定的时间间隔执行数据集的时间点…

Stable Diffusion 系列教程 | 如何获得更高清优质的AI绘画

目录 1 高清修复 1.1 原理 1.2 基本操作 1.3 优缺点 2 UpScale 放大脚本 2.1 原理 2.2 基本操作 2.3 优缺点 3 附加功能放大 3.1 原理 3.2 基本操作 3.3 优缺点 优化出图质量&#xff0c;产出更高清&#xff0c;分辨率更高&#xff0c;更有细节的绘画作品呢&#x…

Nexus 如何配置匿名用户访问一个仓库

现在有这样一个需求&#xff0c;我们需要匿名用户访问 Nexus 的一个公共仓库。 设置 Roles 在满足这个需求之前&#xff0c;我们需要设置一个 Roles。 Role 的名字是可以随填写的。 这里关键的问题在你需要访问的仓库的 View 的权限需要设置 Read 和 Browse 这 2 个权限。 如…

08-信息收集-架构、搭建、WAF等

信息收集-架构、搭建、WAF等 信息收集-架构、搭建、WAF等一、前言说明二、CMS识别技术三、源码获取技术四、架构信息获取技术五、站点搭建分析1、搭建习惯-目录型站点2、搭建习惯-端口类站点3、搭建习惯-子域名站点4、搭建习惯-类似域名站点5、搭建习惯-旁注&#xff0c;c段站点…