问题描述:
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Example:
Given the sorted linked list: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5
源码:
和第108题目有点像,不过改成了链表,麻烦了很多,第一种方法就是每次都找到链表中间点。这样时间和空间都很cuo。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
ListNode* findmedium(ListNode* head){
ListNode *pre=NULL, *slow=head, *fast=head;
while(fast && fast->next){
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
if(pre) pre->next = NULL;
return slow;
}
TreeNode* sortedListToBST(ListNode* head) {
if(!head) return NULL;
ListNode* mid = findmedium(head);
TreeNode* root = new TreeNode(mid->val);
if(head == mid) return root;
root->left = sortedListToBST(head);
root->right = sortedListToBST(mid->next);
return root;
}
};
Solution中给出的第二种方法是将其转换为list然后和108题一样的做,效率同样不高。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
vector<int> st;
public:
void convert(ListNode* head){
ListNode* h = head;
while(h){
st.push_back(h->val);
h = h->next;
}
}
TreeNode* help(int start, int end){
if(start==end) return new TreeNode(st[end]);
else if(start>end) return NULL;
int mid = (start+end)/2;
TreeNode* root = new TreeNode(st[mid]);
root->left = help(start, mid-1);
root->right = help(mid+1, end);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
if(!head) return NULL;
convert(head);
return help(0, st.size()-1);
}
};
Sollution里面有个比较有意思的解法,用一个phead指针,有点像中序遍历,每次处理完左子树后,指针就到了根处。不过效率貌似也不高。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
ListNode* phead;
public:
int findsize(ListNode* head){
ListNode* p = head;
int count = 0;
while(p){
p = p->next; count++;
}
return count;
}
TreeNode* help(int start, int end){
if(start>end) return NULL;
// if(start==end) return new TreeNode(phead->val);
int mid = (start + end)/2;
TreeNode* pleft = help(start, mid-1);
TreeNode* root = new TreeNode(phead->val);
root->left = pleft;
phead = phead->next;
root->right = help(mid+1, end);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
if(!head) return NULL;
phead = head;
return help(0, findsize(head)-1);
}
};