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

题目描述:将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10, -3, 0, 5, 9]

一个可能的答案是:[0, -3, 9, -10, null, 5],它可以表示下面这个高度平衡二叉搜索树:

1
2
3
4
5
    0
/ \
-3 9
/ /
-10 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {

}
}

递归

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0) return null;
return dfs(nums, 0, nums.length - 1);
}

private TreeNode dfs(int[] nums, int left, int right) {
if(left > right) return null;

// 以升序数组的中间元素作为根节点 root
int mid = left + (right -left) / 2;
TreeNode node = new TreeNode(nums[mid]);
node.left = dfs(nums, left, mid - 1);
node.right = dfs(nums, mid + 1, right);
return node;
}
}

复杂度分析:

  • 时间复杂度:O(n),其中 n 是数组的长度。每个数字只访问一次

  • 空间复杂度:O(logn),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(log n)

执行结果:通过

  • 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

  • 内存消耗:39.3 MB, 在所有 Java 提交中击败了98.30%的用户