leetcode--Convert Sorted List to Binary Search Tree
1.题目描述
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
2.解法分析
题意为将一个按升序排列的单链表转换为一个平衡的BST,将单链表转换为平衡树很容易,然后按照先序遍历赋值即可。时间复杂度和空间复杂度都是O(N),时间复杂度上没什么好说的, 但是空间复杂度貌似稍微高了点,因为如果使用O(N)的空间复杂度的话,那么可以直接开辟一个长度为N的数组,然后借助数组可以随机访问的特性写代码。也就是说,这个是个以空间换时间的做法,需要注意的是,虽然是O(N),但是前面的系数在链表够大的时候其实远小于1,比直接用一个长度为N的算法要好得多,虽然暂时给不出证明,但我认为这个的空间复杂度可以收紧到O(logN),而且由于整个程序没有用到递归,其实也抵消了一部分空间浪费。在目前所看的算法中,我的算法速度是最快的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* 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 *sortedListToBST(ListNode *head) {// Start typing your C/C++ solution below
// DO NOT write int main() function
if(!head)return NULL;queue<TreeNode *>temp;int len = 0;
ListNode * cur=head;while(cur!=NULL){len++;cur=cur->next;}
TreeNode *t = new TreeNode(0);len--;
TreeNode *THead = t;temp.push(t);while(true)
{TreeNode * parent = temp.front();temp.pop();if(len>0){t = new TreeNode(0);parent->left = t;temp.push(t);len--;}else break;if(len>0){t = new TreeNode(0);parent->right = t;temp.push(t);len--;}else break;}vector<TreeNode *>treev;treev.push_back(THead);TreeNode *curT=THead;cur=head;while(!treev.empty())
{if(curT->left){treev.push_back(curT->left);curT=curT->left;}
else
{while(!treev.empty())
{curT=treev.back();treev.pop_back();curT->val=cur->val;cur=cur->next;if(curT->right!=NULL){
treev.push_back(curT->right);curT=curT->right;break;
}}}}return THead;
}};
另外在网上搜了几个解法,解法一是最naive的想法,即忽略linklist不能随机访问的特性,仍然用适合于数组的办法来解决问题,当然,如果不算递归开销,这个的空间消耗较少,但是实际上是有递归开销的。最严重的是,时间复杂度这个实际上是O(NlogN)
ref:http://www.cnblogs.com/remlostime/archive/2012/10/29/2744805.html/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int calLen(ListNode *node)
{int len = 0;
while(node)
{len++;node = node->next;}return len;
}TreeNode *createTree(ListNode *node, int left, int right){if (left > right)
return NULL;
int mid = (left + right) / 2;
ListNode *p = node;for(int i = left; i < mid; i++)p = p->next;TreeNode *leftNode = createTree(node, left, mid - 1);TreeNode *rightNode = createTree(p->next, mid + 1, right);TreeNode *tNode = new TreeNode(p->val);
tNode->left = leftNode;tNode->right = rightNode;return tNode;
}TreeNode *sortedListToBST(ListNode *head) {// Start typing your C/C++ solution below
// DO NOT write int main() function
int len = calLen(head);
return createTree(head, 0, len - 1);
}};