从一列已排序的数组中构造BST,如果题目中没有其他要求的话,那么这道题目基本是没办法写的,因为构造出的BST不止一种。注意到题目中有一个很小但是非常关键的条件,就是"height balanced BST",也就是说要root结点左子树和右子树的高度差距尽可能小,又根据BST的性质,如果对其中序遍历的话得到的序列一定是ascending的,所以可以直接在数组中(left + right) / 2的地方得到树的root,这种情况下可以得到最为balanced的树。
同时BST又是一种binary tree,而在处理与binary tree相关的问题的时候,我们需要优先考虑recursion和divide and conquer思想,从而得到结果。另外需要注意的一点是,如果题目给出函数的参数列表与需要递归调用的参数不一致,那么可以另外写一个hepler function,为原来的函数调用。时间复杂度是O(n)而不是O(logn),注意与树相关问题的时间复杂度分析方法,就是考虑每个结点可能会被访问多少次,这里为了构建BST,数组中的每个元素都需要被访问一次,所以时间复杂度是O(n)。代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode helper(int[] nums, int low, int high){
if(low > high) return null;
int mid = low + (high - low) / 2;
TreeNode node = new TreeNode(nums[mid]);
node.left = helper(nums, low, mid - 1);
node.right = helper(nums, mid + 1, high);
return node;
}
public TreeNode sortedArrayToBST(int[] nums) {
if(nums == null || nums.length == 0) return null;
TreeNode head = helper(nums, 0, nums.length - 1);
return head;
}
}
知识点:
1. 处理BST相关问题的时候优先考虑reursion, divide and conquer
2. 注意BST中序遍历的性质,当题目中提到sorted array/list和BST的时候,很可能需要用到这一性质
3. 与树相关问题的时间复杂度分析方法:考虑每个结点可能会被访问多少次
4. 递归函数的参数列表与题目给出的参数列表不同的时候,可以另外写一个recursive function来调用
5. 递归函数要尤其注意基本情况;首先写出corner case