📝 题目描述

题目链接将有序数组转换为二叉搜索树

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

二叉搜索树:左子树上所有节点的值都小于根节点的值;右子树上所有节点的值都大于根节点的值;左右子树也分别为二叉搜索树。
平衡二叉树:该树所有节点的左右子树的高度相差不超过 1。

示例:

示例 1:

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

示例 2:

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

提示:

  • 1 <= nums.length <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums 按 严格递增 顺序排列

💡 解题思路

方法一:中序遍历

题目所给的数组其实就是二叉搜索树的中序遍历,我们很容易想到使用二分法 + 递归构建平衡二叉搜索树。

  • 首先使用二分法选择中间节点 middle 作为根节点;
  • 对于左子树 [left, middle - 1],使用相同方法得到其节点指针;
  • 对于右子树 [middle + 1, right],使用相同方法得到其节点指针;

left > right 时,递归终止。

🔧 代码实现

1、中序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public:
TreeNode* buildTree(vector<int>& nums, int left, int right) {
// 如果左指针越过右指针,说明当前区间为空,返回空节点
if (left > right) {
return nullptr;
}

// 寻找中间节点
int middle = left + (right - left) / 2;

// 构建当前根节点
TreeNode* root = new TreeNode(nums[middle]);

// 递归构建左子树和右子树
root->left = buildTree(nums, left, middle - 1);
root->right = buildTree(nums, middle + 1, right);

return root;
}

TreeNode* sortedArrayToBST(vector<int>& nums) {
return buildTree(nums, 0, nums.size() - 1);
}
};

📊 复杂度分析

1、中序遍历

  • 时间复杂度O(n)O(n),其中 n 是数组的长度。每个数字只访问一次。
  • 空间复杂度O(logn)O(logn),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(logn)O(logn)

🎯 总结

  • 核心思想:能够想到二分法很重要,想好边界条件也很重要。