Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
分析:将链表转化为平衡的BST,采用链表二分法。其中链表的二分法有几种写法,很经典。
ListNode *findMid(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head->next;
ListNode *last = slow;
while(fast && fast->next) {
fast = fast->next->next;
last = slow;
slow = slow->next;
}
return last;
}
ListNode *findMid(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
ListNode *last = slow;
while(fast) {
if(fast) fast = fast->next;
if(fast) fast = fast->next;
if(!fast) break;
if(slow) {
last = slow;
slow = slow->next;
}
}
return last;
}
下面是总体代码,还是二分法解决,其中查找链表中间节点时,需要记录中间节点前一个节点pre_mid。
/**
* 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) {
if(!head) return NULL;
TreeNode *ret = BST(head);
return ret;
}
TreeNode *BST(ListNode *head) {
if(!head) return NULL;
ListNode *pre_mid = findMid(head);
ListNode *mid = NULL;
ListNode *head2 = NULL;
if(pre_mid->next) {
mid = pre_mid->next;
head2 = pre_mid->next->next;
pre_mid->next = NULL;
} else {
head = NULL;
mid = pre_mid;
head2 = NULL;
}
TreeNode *node = new TreeNode(mid->val);
node->left = BST(head);
node->right = BST(head2);
return node;
}
ListNode *findMid(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
ListNode *last = slow;
while(fast) {
if(fast) fast = fast->next;
if(fast) fast = fast->next;
if(!fast) break;
if(slow) {
last = slow;
slow = slow->next;
}
}
return last;
}
};