题目:
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
给定一个排好序(升序)的单链表,把它转化为一个平衡二叉搜索树。
思路:
请先参看”把有序数组转化为二叉搜索树“:http://blog.csdn.net/u012243115/article/details/41940137。
此题稍微麻烦的一点就是链表的遍历不能使用下标,这里可以根据链表的长度求链表的中间结点。
代码1:
/**
* 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)
{
return sortedListToBST(head , ListLength(head));
}
TreeNode *sortedListToBST(ListNode *head , int len)
{
if(len == 0)
return NULL;
if(len == 1)
return new TreeNode(head->val);
TreeNode *root = new TreeNode(nth_node(head,len/2+1)->val);//用链表的中间结点值创建一个二叉树结点
root->left = sortedListToBST(head , len/2);//把链表的前半段len/2 的中间值作为根结点的左结点
root->right = sortedListToBST(nth_node(head,len/2+2),(len-1)/2);//把链表后半段 (len-1)/2 的中间值作为根结点的右结点,后半段链表的首结点为整个链表的第len/2 + 2 个结点
return root;
}
//返回当前链表的第 len 个结点
ListNode *nth_node(ListNode *node, int len)
{
while(--len)
{
node = node->next;
}
return node;
}
//求链表的长度
int ListLength(ListNode *head)
{
int len = 0 ;
ListNode *p = head;
while(p)
{
len++;
p = p->next;
}
return len;
}
};
代码2:
/**
* 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)
{
int end = ListLength(head) - 1;
return sortedListToBST(head , 0 , end);
}
TreeNode *sortedListToBST(ListNode *head , int begin , int end)
{
if(begin > end)
return NULL;
int mid = (begin + end)/2;
ListNode *p = head;
//p为中间结点
for(int i = begin ; i < mid ; i++)
{
p = p->next;
}
TreeNode *root = new TreeNode(p->val);//用链表的中间结点值创建一个二叉树结点
root->left = sortedListToBST(head , begin , mid-1);//把链表的前半段的中间值作为根结点的左结点
root->right = sortedListToBST(p->next,mid + 1 , end);//把链表后半段的中间值作为根结点的右结点,后半段链表的首结点为p->next
return root;
}
//求链表的长度
int ListLength(ListNode *head)
{
int len = 0 ;
ListNode *p = head;
while(p)
{
len++;
p = p->next;
}
return len;
}
};