当前位置: 首页 > news >正文

【LeetCode热题100道笔记】将有序数组转换为二叉搜索树

题目描述

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

示例 1:
在这里插入图片描述
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
在这里插入图片描述

示例 2:
在这里插入图片描述
输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列

思考:分治思想构建平衡BST

核心是分治递归:每次取数组中间元素作为当前根节点,将数组分为“左子数组”(根左侧元素)和“右子数组”(根右侧元素),分别递归构建左、右子树——左子数组构建左子树(值均小于根),右子数组构建右子树(值均大于根),最终形成平衡BST。

采用左闭右开区间 [start, end) 划分数组,可简化边界处理(终止条件为 start >= end,即空区间)。

算法过程

  1. 初始化递归:调用辅助函数 buildBST,传入数组 nums 及初始区间 [0, nums.length)(覆盖整个数组)。
  2. 递归终止条件:若区间 start >= end(空区间,无元素可构建节点),返回 null
  3. 构建当前根节点
    • 计算区间中点 mid = start + Math.floor((end - start) / 2)(用此写法避免 start + end 溢出);
    • nums[mid] 为值创建当前根节点,确保根节点是区间中间元素,左右子树元素数量差≤1(保证平衡)。
  4. 递归构建子树
    • 左子树:用左子区间 [start, mid) 递归构建(元素均小于当前根,满足BST左子树特性);
    • 右子树:用右子区间 [mid+1, end) 递归构建(元素均大于当前根,满足BST右子树特性)。
  5. 返回结果:递归回溯时,返回当前根节点,最终形成完整的平衡BST。

时空复杂度

  • 时间复杂度:O(n),n为数组长度。
    原因:每个数组元素仅被用于创建一个节点(递归过程中每个元素对应一个根/子节点),每个节点的构建操作(创建节点、递归调用)均为O(1),总操作次数与数组长度线性相关。
  • 空间复杂度:O(log n),n为数组长度。
    原因:递归调用栈深度取决于平衡BST的高度——平衡BST的高度为 log n(如n=5时高度2,n=7时高度3),最坏情况下(无额外空间消耗),空间复杂度由递归栈决定,为O(log n)。

代码(左闭右开区间实现)

/*** Definition for a binary tree node.* function TreeNode(val, left, right) {*     this.val = (val===undefined ? 0 : val)*     this.left = (left===undefined ? null : left)*     this.right = (right===undefined ? null : right)* }*/
/*** @param {number[]} nums* @return {TreeNode}*/
var sortedArrayToBST = function(nums) {// 初始区间:左闭右开 [0, nums.length),覆盖整个数组return buildBST(nums, 0, nums.length);
};// 辅助函数:基于区间 [start, end) 构建平衡BST
function buildBST(nums, start, end) {// 终止条件:空区间(无元素可构建节点),返回nullif (start >= end) return null;// 计算中点:避免 start + end 溢出(如start和end均接近Number.MAX_SAFE_INTEGER)const mid = start + Math.floor((end - start) / 2);// 以中点元素为根,保证左右子树元素数量差≤1,天然平衡const root = new TreeNode(nums[mid]);// 递归构建左子树:左子区间 [start, mid)(元素均小于root.val)root.left = buildBST(nums, start, mid);// 递归构建右子树:右子区间 [mid+1, end)(元素均大于root.val)root.right = buildBST(nums, mid + 1, end);return root;
}

关键逻辑解析

  1. 为何选中间元素为根?
    升序数组的中间元素可将数组分为“长度相等或差1”的左右子数组,递归构建的左右子树高度差≤1,天然满足“平衡”要求;同时,左子数组元素均小于中间元素、右子数组均大于中间元素,满足BST的数值特性。

  2. 为何用左闭右开区间?
    左闭右开区间的终止条件 start >= end 更简洁(空区间直接返回null),且子区间划分无需调整边界(左子树 [start, mid)、右子树 [mid+1, end),无重叠且覆盖原区间),避免左闭右闭区间中 start > end 的复杂判断。

  3. 中点计算的溢出问题
    若直接写 mid = Math.floor((start + end) / 2),当 startend 均接近最大值时,start + end 可能超出JavaScript整数安全范围,导致计算错误;而 start + Math.floor((end - start) / 2) 可避免此问题,结果与前者一致且更安全。


文章转载自:

http://VO5FrnOR.wckrL.cn
http://jILidelS.wckrL.cn
http://pUxHzNjp.wckrL.cn
http://2VW9RzZ0.wckrL.cn
http://d34ZVMsV.wckrL.cn
http://bAoAYre0.wckrL.cn
http://Kh9zdiKq.wckrL.cn
http://D00HB4iv.wckrL.cn
http://8nOdKtb2.wckrL.cn
http://HAJkaaFP.wckrL.cn
http://GHxbwWTU.wckrL.cn
http://RiPrXT2i.wckrL.cn
http://ARQJ6UIv.wckrL.cn
http://svIggRtw.wckrL.cn
http://KPDP3Wt7.wckrL.cn
http://QpOf2Qft.wckrL.cn
http://vwS29d4W.wckrL.cn
http://zYgMIgg3.wckrL.cn
http://kqwWHhgw.wckrL.cn
http://0D1CyrLP.wckrL.cn
http://pDckYRsR.wckrL.cn
http://2UjZKdP3.wckrL.cn
http://8cBGA18j.wckrL.cn
http://qzwb5ezM.wckrL.cn
http://tMRkxmRA.wckrL.cn
http://VpBjEjUe.wckrL.cn
http://sLVDnknD.wckrL.cn
http://5eff9R5J.wckrL.cn
http://lu2Gzk7v.wckrL.cn
http://5ofSm3Ua.wckrL.cn
http://www.dtcms.com/a/370874.html

相关文章:

  • 【LeetCode热题100道笔记】二叉树的直径
  • 2023年ASOC SCI2区TOP,改进元启发式算法+考虑医护人员技能水平的家庭健康护理路径规划,深度解析+性能实测
  • wpf之TextBlock
  • Docker安装Ubuntu搭建Android SDK编译环境
  • Golang中逃逸现象, 变量“何时栈?何时堆?”
  • 我用Claude Code 开发了一个浏览器插件
  • LRU 算法和 LFU 算法有什么区别?
  • Cursor安装使用 与 Cursor网页端登录成功,客户端怎么也登陆不上
  • vue + ant-design-vue + vuedraggable 实现可视化表单设计器
  • 未来教育行业的 Go 服务开发解决方案与实践
  • 为什么ubuntu大文件拷贝会先快后慢?
  • SQL-窗口函数
  • buuctf-鸡藕椒盐味,[NPUCTF2020]EzRSA,[WUSTCTF2020]大数计算
  • OpsManage 项目启动脚本与 Docker 配置深度分析
  • 智能制造——解读97页汽配行业ERP整体解决方案【附全文阅读】
  • LIO-SAM 算法从入门到部署实践
  • ES6 核心特性详解:从变量声明到函数参数优化
  • 云手机在企业办公中的作用
  • 2025高教社国赛数学建模C题参考论文(含模型和代码)
  • RPC 和 HTTP 的区别
  • 通过Idea 阿里插件快速部署java jar包
  • 在Ubuntu 22.04系统中无需重启设置静态IP地址
  • 数据结构中排序的时间、空间复杂度以及稳定性
  • 面试开发工程师需要做哪些准备
  • hot100-贪心算法(附图解思路)
  • 京东商品属性API数据解析:颜色、尺寸与材质
  • 附051.Kubernetes Karmada kubectl 插件部署联邦及使用
  • 从 Excel 趋势线到机器学习:拆解 AI 背后的核心框架​
  • 嵌入式学习笔记--Linux系统编程阶段--DAY06进程间通信-消息队列
  • 【Beetle RP2350】摇杆控制自定义角度旋转舵机