【力扣 - 将有序数组转化为二叉搜索树】

题目描述

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

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
在这里插入图片描述
在这里插入图片描述

题解

前言

二叉搜索树的中序遍历是升序序列,题目给定的数组是按照升序排序的有序数组,因此可以确保数组是二叉搜索树的中序遍历序列。

给定二叉搜索树的中序遍历,是否可以唯一地确定二叉搜索树?答案是否定的。如果没有要求二叉搜索树的高度平衡,则任何一个数字都可以作为二叉搜索树的根节点,因此可能的二叉搜索树有多个。
在这里插入图片描述
如果增加一个限制条件,即要求二叉搜索树的高度平衡,是否可以唯一地确定二叉搜索树?答案仍然是否定的。
在这里插入图片描述
直观地看,我们可以选择中间数字作为二叉搜索树的根节点,这样分给左右子树的数字个数相同或只相差 111,可以使得树保持平衡。如果数组长度是奇数,则根节点的选择是唯一的,如果数组长度是偶数,则可以选择中间位置左边的数字作为根节点或者选择中间位置右边的数字作为根节点,选择不同的数字作为根节点则创建的平衡二叉搜索树也是不同的。
在这里插入图片描述
确定平衡二叉搜索树的根节点之后,其余的数字分别位于平衡二叉搜索树的左子树和右子树中,左子树和右子树分别也是平衡二叉搜索树,因此可以通过递归的方式创建平衡二叉搜索树。

递归的基准情形是平衡二叉搜索树不包含任何数字,此时平衡二叉搜索树为空。

在给定中序遍历序列数组的情况下,每一个子树中的数字在数组中一定是连续的,因此可以通过数组下标范围确定子树包含的数字,下标范围记为 [left,right]。对于整个中序遍历序列,下标范围从 left=0right=nums.length−1。当 left>right 时,平衡二叉搜索树为空。

方法一:中序遍历,总是选择中间位置左边的数字作为根节点

选择中间位置左边的数字作为根节点,则根节点的下标为 mid=(left+right)/2,此处的除法为整数除法。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     struct TreeNode *left;*     struct TreeNode *right;* };*/// Helper function to recursively build a balanced BST from a sorted array
struct TreeNode* sortedArrayToBSTHelper(int* nums, int left, int right) {// Base case: if left index is greater than right index, return NULLif (left > right) {return NULL;}// Calculate the middle indexint mid = (right + left) / 2;// Create a new TreeNode with the value at the middle indexstruct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = nums[mid];// Recursively build the left and right subtreesroot->left = sortedArrayToBSTHelper(nums, left, mid - 1);root->right = sortedArrayToBSTHelper(nums, mid + 1, right);return root;
}// Main function to convert a sorted array to a balanced BST
struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {// If the array is empty, return NULLif (numsSize == 0) {return NULL;}// Call the helper function with the full range of the arrayreturn sortedArrayToBSTHelper(nums, 0, numsSize - 1);
}

复杂度分析

时间复杂度:O(n),其中 n 是数组的长度。每个数字只访问一次。

空间复杂度:O(log⁡ n),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(log ⁡n)

方法二:中序遍历,总是选择中间位置右边的数字作为根节点

选择中间位置右边的数字作为根节点,则根节点的下标为 mid=(left+right+1)/2,此处的除法为整数除法。

struct TreeNode* helper(int* nums, int left, int right) {if (left > right) {return NULL;}// 总是选择中间位置右边的数字作为根节点int mid = (left + right + 1) / 2;struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = nums[mid];root->left = helper(nums, left, mid - 1);root->right = helper(nums, mid + 1, right);return root;
}struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {return helper(nums, 0, numsSize - 1);
}

复杂度分析

时间复杂度:O(n),其中 n 是数组的长度。每个数字只访问一次。

空间复杂度:O(log ⁡n),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(log⁡ n)。

方法三:中序遍历,选择任意一个中间位置数字作为根节点

选择任意一个中间位置数字作为根节点,则根节点的下标为 mid=(left+right)/2 和 mid=(left+right+1)/2 两者中随机选择一个,此处的除法为整数除法。

struct TreeNode* helper(int* nums, int left, int right) {if (left > right) {return NULL;}// 选择任意一个中间位置数字作为根节点int mid = (left + right + rand() % 2) / 2;struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));root->val = nums[mid];root->left = helper(nums, left, mid - 1);root->right = helper(nums, mid + 1, right);return root;
}struct TreeNode* sortedArrayToBST(int* nums, int numsSize) {return helper(nums, 0, numsSize - 1);
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/solutions/312607/jiang-you-xu-shu-zu-zhuan-huan-wei-er-cha-sou-s-33/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

相关文章

黑马JavaWeb开发跟学(一)Web前端开发HTML、CSS基础

黑马JavaWeb开发一.Web前端开发HTML、CSS基础 引子、Web开发介绍传统路线本课程全新路线本课程适用人群课程收获一、什么是web开发二、网站的工作流程三、网站的开发模式四、网站的开发技术 前端开发基础一、前端开发二、HTML & CSS2.1 HTML快速入门2.1.1 操作第一步第二步…

Arduino中安装ESP32网络抽风无法下载 暴力解决办法 python

不知道什么仙人设计的arduino连接网络部分,死活下不下来。(真的沙口,第一次看到这么抽风的下载口) 操作 给爷惹火了我踏马解析json选zip直接全部下下来 把这个大家的开发板管理地址下下来跟后面python放在同一目录下&#xff0c…

FDTD算法总结

计算电磁学(Computational Electromagnetics, CEM)是通过数值计算来研究电磁场的交叉学科。 数值求解电磁学问题的方法可以分成频域(Frequency Doamin, FD)、时域(Time Domain, TD)等两类。 频域法基于时谐微分,通过对多个采样值的傅里叶逆变换得到所需的脉冲响应…

构建高效教学平台系统:关键要素与最佳实践

随着在线教育的迅速发展,教学平台系统成为了教育行业不可或缺的一部分。本文将总结构建高效教学平台系统的关键要素,并介绍最佳实践,以帮助教育机构和企业打造具有竞争力的教学平台系统。 引言: 随着信息技术的不断进步和普及&…

神经网络系列---分类度量

文章目录 分类度量混淆矩阵(Confusion Matrix):二分类问题二分类代码多分类问题多分类宏平均法:多分类代码多分类微平均法: 准确率(Accuracy):精确率(Precision)&#xf…

K8s安全一

Kubernetes是一个开源的,用于编排云平台中多个主机上的容器化的应用,目标是让部署容器化的应用能简单并且高效的使用, 提供了应用部署,规划,更新,维护的一种机制。其核心的特点就是能够自主的管理容器来保证云平台中的…

值得推荐收藏的5款顶级免费数据恢复软件!

今天分享5个超级简单又适合电脑小白的恢复删除的文件的恢复方法! 在我们的日常生活中,偶尔会因为误删除或者清空回收站等原因导致数据丢失。对于电脑小白来说,这或许是一个非常棘手的问题。但是,不用太担心,今天我为大…

【C++那些事儿】C++入门 | 命名空间 | 缺省参数 | 引用 | 内联函数 | auto关键字 | 范围for循环 | nullptr

📷 江池俊: 个人主页 🔥个人专栏: ✅数据结构冒险记 ✅C那些事儿 🌅 有航道的人,再渺小也不会迷途。 文章目录 前言1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4. 缺…

模型上下文长度达到10000000,又一批创业者完蛋了?

没有疑问,Gemini 1.5 Pro的隆重推出被Sora抢了风头。 社交平台X上OpenAI介绍Sora的第一条动态,现在已经被浏览了超过9000万次,而关于Gemini 1.5 Pro热度最高的一条,来自谷歌首席科学家Jeff Dean,区区123万人。 或许J…

【设计模式】策略模式及函数式编程的替代

本文介绍策略模式以及使用函数式编程替代简单的策略模式。 策略模式 在策略模式(Strategy Pattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式定义了一系列算法或策略,并将每个算法封装在独立…

Jenkins解决Host key verification failed (2)

Jenkins解决Host key verification failed 分析原因情况 一、用OpenSSH的人都知ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告,避免…

基于SpringBoot的航班进出港管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

【Java程序设计】【C00319】基于Springboot的志愿服务管理系统(有论文)

基于Springboot的志愿服务管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的志愿服务管理系统设计与实现,本系统有管理员以及用户二种角色权限 管理员:首页、个人中心、管理员管理、…

【MATLAB源码-第146期】基于matlab的信源编码仿真GUI,对比霍夫曼编码,算术编码和LZ编码。

操作环境: MATLAB 2022a 1、算法描述 霍夫曼编码、算术编码和LZ编码是三种广泛应用于数据压缩领域的编码技术。它们各自拥有独特的设计哲学、实现方式和适用场景,因此在压缩效率、编解码速度和内存使用等方面表现出不同的特点。接下来详细描述这三种编…

Base64 编码 lua

Base64 编码 -- Base64 字符表 local base64_chars { A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,…

freeswitch 权威指南 --- 高级篇

官网文档:https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/ 关于 freeswitch 的公开教程:https://zhuanlan.zhihu.com/p/451981734 内容来自 《FreeSWITCH 权威指南》:目录:https://juejin.cn/post/702058079…

Vue+SpringBoot打造开放实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

什么是智慧公厕?如何打造智慧公厕?

近年来,随着城市信息化建设的不断推进,智慧公厕的建设成为我国城市发展的重要一环。以智能化管理为核心,将公厕纳入互联互通的“智慧城市”大数据平台,使得公厕管理更加高效便捷,为市民提供更好的公共服务。本文将以智…

零基础C++开发上位机--基于QT5.15的串口助手(一)

嵌入式开发的过程中,大部分我们的代码是无法一次成功的。这时候我们大部分的工程师可能最熟练的调试方法是printf函数,打印随意一个数据,来观察当前运行的函数是否执行正确。我们连接的工具有各个大神做的串口助手。另外,在做一般…

[RCTF2015]EasySQL1 题目分析与详解

一、题目介绍: 1、题目来源: BUUCTF网址 2、题目介绍: 拿到flag。 二、解题思路: 我们发现题目首页有登录和注册账号两个选项,我们首先尝试注册账号,尝试注册username为admin的账号,输入密码…