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() functionif(!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() functionint len = calLen(head);return createTree(head, 0, len - 1);}};