题目如下:
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
分析如下:
递归进行。每次找到排序数组的中点,中点左边的子排序数组构成左子树,中点右边的子排序数组构成右子树。就这样递归进行。由于每次都几乎做到了二分,所以每次的左子树和右子树的节点数量是均衡的,所以最后得到的BST树是balanced。(我不知道如何严格地证明它。)
其中的边界情况是:
(1) 假设当前情况只有array[0]这一个数。那么显然不需要求这段数组的中点了,这个数单独构造一个节点并且返回。它对应下面代码中的边界情况1,start==end的情况。
(2) 假设当前情况有array[0]和array[1]两个数,那么按照代码拆分的中点,左子树root,右子树root这三个点种,真正可以用来造节点的只有中点和右子树root。所以对于左子树root,返回NULL就行。对应下面代码中的边界情况2,start>end的情况。
我的代码
//92ms过大集合
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* _sortedArrayToBST(vector<int>& num, int start, int end){
if(start==end) //边界情况1
return new TreeNode(num[start]);
if(start>end) { //边界情况2
return NULL;
}
//int mid=(start+end)/2; 这个写法可以改进为下面的这种写法,防止溢出
int mid=start+(end-start)/2;
TreeNode* root=new TreeNode(num[mid]);
root->left=_sortedArrayToBST(num, start,mid-1);
root->right=_sortedArrayToBST(num,mid+1,end);
return root;
}
TreeNode *sortedArrayToBST(vector<int> &num) {
if(num.size()==0)
return NULL;
int mid=(0+(int)num.size()-1)/2;
TreeNode* root=new TreeNode(num[mid]);
root->left=_sortedArrayToBST(num, 0, mid-1);
root->right=_sortedArrayToBST(num, mid+1, (int)num.size()-1);
return root;
}
};
小结
(1)代码结构基本上和二分搜索很像
(2)因为是在数组中,所以可以用数组下标直接获取一个元素,获取每个元素的时间复杂度是O(1),而一共对O(N)个元素做了操作,所以时间复杂为O(N)
(3)如果把数组改成链表,就成为了下道题目。采用和本题类似的方式来解答,由于链表没发用下标直接获取一个元素,而是需要遍历,在二分的情况下,每次遍历链表的时间复杂度为lgN,同样针对每个元素都坐这样的操作,所以总的时间复杂度为O(N*lgN),但是官网上提到了一种更加NB的做法,时间复杂度为O(N)。
update: 2014-10-14
主要更新了边界条件的写法,只需要start > end这一种边界条件就够了。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode* mySortedArrayToBST(vector<int> &num, int start, int end) {
if (start > end)
return NULL;
int mid = start + ((end - start) >> 1);
TreeNode* node = new TreeNode(num[mid]);
node->left = mySortedArrayToBST(num, start, mid - 1);
node->right = mySortedArrayToBST(num, mid + 1, end);
}
public:
TreeNode *sortedArrayToBST(vector<int> &num) {
if (num.size() == 0)
return NULL;
return mySortedArrayToBST(num, 0, num.size() - 1);
}
};