将有序数组转换为二叉搜索树
问题描述
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
背景知识介绍
- 平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
- 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
示例
给定有序数组: [-10,-3,0,5,9]
,
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
给定有序数组: [-10,-3,0,5,9],
一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
分析
二叉搜索树的中序遍历是一个升序序列
将有序数组作为输入,可以把该问题看做 根据中序遍历序列创建二叉搜索树,那么这道题就变成了,按照一个数组序列,构建一颗二叉树,该树要满足高度平衡
需要注意,满足高度平衡构建出来的树,结果并不是唯一的,这取决与你选择根结点的策略:
高度平衡意味着每次必须选择中间数字作为根节点。这对于奇数个数的数组是有用的,但对偶数个数的数组没有预定义的选择方案
如[1,2,3,4,5,6]
你可以选择3或者4作为根结点,依次类推…
在此,偶数情况下,我选择每次都已中间结点左边的结点作为根结点
所以,求根结点的算式为:int mid = left + (right - l) / 2
;
核心代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] nums ;
public TreeNode sortedArrayToBST(int[] nums) {
if(nums==null) return null ;
this.nums = nums ;
return buildTree(0,nums.length-1) ;
}
public TreeNode buildTree(int l,int r){
if(l>r) return null ;
int mid = l + (r - l) / 2 ;
TreeNode root = new TreeNode(nums[mid]) ;
root.left = buildTree(l,mid-1) ;
root.right = buildTree(mid+1,r) ;
return root ;
}
}
性能分析
时间复杂度:O(N)
,每个元素只访问一次。
空间复杂度:O(N)
,二叉搜索树空间O(N)
,递归栈深度 O(logN)
。
==========update by 2020 4/16 ========
C++可运行源代码(经VS2015、devC++编译运行通过)
#include "string.h"
#include "stdio.h"
#include "stdlib.h"