LongDz 的数字文墨提案

108. 将有序数组转换为二叉搜索树

3 min

题目

解法:递归构建

思路

核心思想是分治递归:始终选择子数组的中间元素作为根节点,确保左右子树节点数平衡。

正确性证明:由于数组已排序,中间元素左侧所有值必然小于根节点,右侧所有值必然大于根节点,满足BST性质。左右子数组长度最多相差1,递归构建可保证每棵子树都是平衡的,从而整棵树高度差不超过1。归纳基础是空区间返回nullptr,归纳步骤通过均匀分割维持平衡性。

  • Step 1: 定义递归函数build,接收数组和左右边界l、r
  • Step 2: 若l > r,返回nullptr表示空子树
  • Step 3: 计算中间位置mid = l + (r - l) / 2
  • Step 4: 创建根节点,值为nums[mid]
  • Step 5: 递归构建左子树,区间为[l, mid-1]
  • Step 6: 递归构建右子树,区间为[mid+1, r]
  • Step 7: 返回根节点

复杂度

  • 时间复杂度: O(n)O(n)
  • 空间复杂度: O(logn)O(\log n)

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return build(nums, 0, nums.size() - 1);
    }
    TreeNode* build(vector<int>& nums, int l, int r){
        if(l > r) return nullptr;
        int mid = l + (r - l) / 2;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = build(nums, l, mid - 1);
        root->right = build(nums, mid + 1, r);
        return root;
    }
};