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

题目

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

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

思路(Sweetiee)

题意:根据升序数组,恢复一棵高度平衡的(该树所有节点的左右子树高度相差不超过1)二叉搜索树BST。

分析:BST的中序遍历是升序的,所以本题等同于根据中序遍历的序列恢复二叉搜索树。
所以我们可以 以升序序列中的任一个元素 作为根节点, 以该元素左边的升序序列构建左子树,以该元素右边的升序序列构建右子树。这样就可以得到一棵二叉搜索树。
因为本题要求平衡,所以我们需要选择升序序列的中间元素作为根节点

盲点分析

用递归构建BST

  1. 分治思想:将数组划分为左右两部分,分别构建左右子树。
  2. 每个递归调用,对应树中的一个节点,然后递归的构建其左子树和右子树。

递归终止条件:当lo>hi时,表示当前子数组为空,返回null,对应叶子节点的子节点

时间复杂度:每个元素访问一次O(n)
空间复杂度:递归调用栈的深度为O(log n)

代码

public class o108 {
    private class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {}
        TreeNode(int val) {
            this.val = val;
        }
        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    public TreeNode sortedArrayToBST(int[] nums) {
        return dfs(nums, 0, nums.length - 1);
    }
    
    private TreeNode dfs(int[] nums, int lo, int hi) {
        if (lo > hi) {
            return null;
        }
        // 以升序数组的中间元素作为根节点root
        int mid = lo + (hi - lo) / 2;
        TreeNode root = new TreeNode(nums[mid]);
        // 递归的构建root的左子树与右子树。
        root.left = dfs(nums, lo, mid - 1);
        root.right = dfs(nums, mid + 1, hi);
        return root;
    }
}
posted @ 2025-05-01 10:50  kuki'  阅读(40)  评论(0)    收藏  举报