D

当前:LC108 · 将有序数组转换为二叉搜索树 · 首次出现于 Day 24 · 路径:顶栏「56天打卡」→ 点击 LC 题号 → 逐题动画

LC108 · 将有序数组转换为二叉搜索树 · 算法执行实验台

有序数组 · 中点分治 · 平衡 BST

本题不是简单地把元素塞进 BST,而是同时满足: BST(左 < 根 < 右)与 高度平衡(左右子树高度差尽量小)。 核心手段:在有序数组上每次选 mid 作根,把区间均分给左右递归。

nums = [-10, -3, 0, 5, 9]
升序 · 分治选 mid

核心机制 · 选中点分治

  • · 本题同时满足两件事:BST(左 < 根 < 右)+ 高度平衡(左右子树高度差尽量小)。
  • · 数组已有序:选 mid 作根时,左半都小于根、右半都大于根,天然满足 BST。
  • · 总选左端会让树退化成链表;选中点能把数组平均分给左右,树尽量矮。
  • · build(lo, hi) 的语义:把 nums[lo..hi] 这一段有序数组转换成一棵高度平衡 BST。
有序数组+中点均分

数组已有序,选 mid 天然满足 BST;均分左右保证平衡。递归边界 lo > hi → nil。

  • mid := lo + (hi-lo)/2
  • node.Left = build(lo, mid-1)
  • node.Right = build(mid+1, hi)
完整调用链(示例 nums)
  1. build(0,4) → mid=2, root=0
  2. ├ build(0,1) → mid=0, root=-10
  3. │ └ build(1,1) → root=-3
  4. └ build(3,4) → mid=3, root=5
  5. └ build(4,4) → root=9
1/15 · 读题 · 双约束
15 步分镜:
Step 1读题 · 双约束

读题:不只是建 BST,还要高度平衡

给定升序数组 nums,转成一棵二叉搜索树,且要「高度平衡」——任意节点左右子树高度差不超过 1。两个约束同时成立:BST 性质(左 < 根 < 右)+ 分治时让左右规模尽量接近。示例 nums = [-10, -3, 0, 5, 9]。

· 本题同时满足两件事:BST(左 < 根 < 右)+ 高度平衡(左右子树高度差尽量小)。

· 数组已有序:选 mid 作根时,左半都小于根、右半都大于根,天然满足 BST。

· 总选左端会让树退化成链表;选中点能把数组平均分给左右,树尽量矮。

· build(lo, hi) 的语义:把 nums[lo..hi] 这一段有序数组转换成一棵高度平衡 BST。

为什么

本题同时满足两件事:BST(左 < 根 < 右)+ 高度平衡(左右子树高度差尽量小)。

数组区间 · nums[lo..hi]
nums-10[0]lo-3[1]0[2]5[3]9[4]hi[0..4]

递归栈 · build(lo, hi)

(空栈)

状态表 · lo / hi / mid / 栈

lohimidroot左区间右区间调用栈
04[]

当前切片:[-10, -3, 0, 5, 9]

动作

读题BST + 平衡

正在生成的 BST
等待第一个节点…
Go · build(lo, hi) 分治
1func sortedArrayToBST(nums []int) *TreeNode {
2 var build func(lo, hi int) *TreeNode
3 build = func(lo, hi int) *TreeNode {
4 if lo > hi {
5 return nil
6 }
7 mid := lo + (hi-lo)/2
8 node := &TreeNode{Val: nums[mid]}
9 node.Left = build(lo, mid-1)
10 node.Right = build(mid+1, hi)
11 return node
12 }
13 return build(0, len(nums)-1)
14}
复杂度
时间
O(n)
辅助空间
O(log n)
总空间(含输出树)
O(n)

每个数组元素只创建一次节点,共 n 次递归建树。

递归调用栈深度等于平衡 BST 高度,约 log n。

若把输出的 n 个节点计入,总空间为 O(n);辅助空间仍是 O(log n) 栈。

面试怎么答

数组已经有序,所以选择中间元素作为根时,左半部分都小于根,右半部分都大于根,天然满足 BST。为了让树高度平衡,每次都选择中点,把数组平均分给左右子树。递归处理左右区间即可。每个元素只创建一次节点,时间 O(n)。递归深度是平衡树高度,所以辅助空间 O(log n)。

常见误区
误区一:以为答案唯一

mid 取左中位数 (lo+hi)/2 或右中位数 (lo+hi+1)/2 都可能得到合法的高度平衡 BST,LeetCode 接受多种结构。

误区二:空间复杂度写成 O(1)

忽略了递归栈 O(log n)。输出树本身占 O(n),但面试里「辅助空间」通常指栈,不是 O(1)。

误区三:只背代码,不说为什么平衡

必须解释「选中点 → 左右规模接近 → 树高 O(log n)」,否则面试官会追问 mid 的意义。

误区四:base case 写错

lo > hi 必须 return nil;mid-1 / mid+1 切分不能漏,否则越界或无限递归。