题目
给定一个单元链表,元素按升序排序,将其转换为高度平衡的BST。对于这个问题,一个高度平衡的二叉树是指:其中每个节点的两个子树的深度相差不会超过 1 的二叉树。
例子:
给定的排序链表: [-10, -3, 0, 5, 9],
则一个可能的答案是:[0, -3, 9, -10, null, 5]
0
/
-3 9
/ /
-10 5
代码
/**
* 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:
TreeNode* sortedChild(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;
//--------------------精华部分Begin-----------------------
while (temp!=tail&&temp->next!=tail)
{
//一个前进一个位置,一个前进2个位置,最后mid会到中间,注意判断条件
mid = mid->next;
temp = temp->next->next;
}
//--------------------精华部分End-----------------------
TreeNode* root = new TreeNode(mid->val);
root->left = sortedChild(head, mid);
root->right = sortedChild(mid->next, tail);
return root;
}
public:
TreeNode * sortedListToBST(ListNode* head)
{
return sortedChild(head, NULL);
}
};
算法思路
上面给出的是我认为一个非常完美的解法,说来惭愧,这道题我在思路上大致相同,都是通过递归每次寻找中位值来插入结点,而这个解法的精髓之处就在于它的查找中间结点算法
的思想,通过两个指针前进步数设置为1和2来进行寻找中间位置,值得记录并学习,相信在很多树和链表的算法中这个寻找中间值思想都能够用上,特此记录一下,此外还要要注意前进的判断条件!。
而与此题相关的是109. 有序链表转换二叉搜索树
,这道题是一道更为简单的题目,由于数组是Random Access,所以我们可以在O(1)时间获得中间值。