题目描述
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
解题思路
这道题有一道非常类似的题:Convert Sorted Array to Binary Search Tree,这道题的意思是将排序数组变成二叉搜索树。二叉搜索树的特点是树的左子树都比根节点小,树的右子树都比根节点大。数组既然已经排序,那么只需用递归的方式完成就可以了。题目的代码如下:
/**
* 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:
TreeNode* sortedArrayToBST(vector<int>& nums) {
int n=nums.size();
if(n==0) return NULL;
return buildTree(nums,0,n-1);
}
TreeNode* buildTree(vector<int>& nums,int start,int end){
if(start>end) return NULL;
if(start == end) return new TreeNode(nums[start]);
int mid=(start+end)/2;
TreeNode *root=new TreeNode(nums[mid]);
root->left=buildTree(nums,start,mid-1);
root->right=buildTree(nums,mid+1,end);
return root;
}
};
但是对于链表来说是不能通过下标来直接访问链表的节点的。所以这道题的难点就是寻找中间节点,这里我们可以采用双指针的方法,一个指针一次跳一步,另一个指针一次跳两步,则等到快指针到达链表终点,则慢指针才到达链表中点。然后就可以采取递归的思路啦~~
代码
class Solution {
public:
TreeNode *sortedListToBST(ListNode *head)
{
return sortedListToBST( head, NULL );
}
private:
TreeNode *sortedListToBST(ListNode *head, ListNode *tail)
{
if( head == tail )
return NULL;
if( head->next == tail ) //
{
TreeNode *root = new TreeNode( head->val );
return root;
}
ListNode *mid = head, *temp = head;
while( temp != tail && temp->next != tail ) // 寻找中间节点
{
mid = mid->next;
temp = temp->next->next;
}
TreeNode *root = new TreeNode( mid->val );
root->left = sortedListToBST( head, mid );
root->right = sortedListToBST( mid->next, tail );
return root;
}
};