一、题目描述
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
二、代码思路
首先思考几个问题:
- 二叉搜索树的中序遍历就是一个升序的数据,那么只给中序遍历序列是否构成一棵唯一的二叉搜索树 ? 并不能,根节点不确定
- 如果保证二叉搜索树高度平衡,那么能构成唯一的二叉搜索树吗 ?并不能,同样的节点数为奇数能找到唯一根节点,但是偶数可以选择两个根节点,根节点不确定。
所以我们知道构造出的二叉搜索树可能会很多, 这也给我们一个思路:
我们想要构造平衡的二叉搜索树,那么根节点两边的左右子树节点个数只能最多相差1个,这样我们通过二分就能找到根节点。
然后,根据该根节点二分左右子树,再分别按照同样的逻辑在左右子树中找根节点,直到找完所有节点。
所以本题的思路与上一题,根据中序遍历与前序遍历构造出二叉树的思路非常类似,而且递归的实现也很类似。
三、代码题解
package leetcode.lc20221215;
import java.util.ArrayList;
import java.util.List;
/*
* @author lzy
* @version 1.0
* */
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 class Solution02 {
private List<Integer> list = new ArrayList<>();
public TreeNode balanceBST(TreeNode root) {
inorderTran(root);
return buildTree(0, list.size());
}
//1. 确定递归返回值与参数
public void inorderTran(TreeNode root) {
//2. 递归退出条件
if (root == null) {
return;
}
//3. 本层处理逻辑
if (root.left != null) {
inorderTran(root.left);
}
list.add(root.val);
if (root.right != null) {
inorderTran(root.right);
}
}
//1. 递归函数返回值与参数
public TreeNode buildTree(int left, int right) {
//2. 退出条件
if (left > right) {
return null;
}
//3. 本层逻辑
int mid = (left + right) / 2;
TreeNode root = new TreeNode(list.get(mid));
root.left = buildTree(left, mid - 1);
root.right = buildTree(mid + 1, right);
return root;
}
}
单看buildTree,时间复杂度为o(n),空间复杂度为01;