力扣109:有序链表转换二叉搜索树
题目
给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为 平衡 二叉搜索树。
思路
想完成这道题我们得先知道什么是平衡二叉搜索树,平衡二叉搜索树的定义是左右子树的高度差不能超过1。
所以这道题的关键是找到一个合适的根节点,因为如果根节点太小就会导致右子树的高度远大于左子树,根节点太大就导致左子树的高度远大于右子树也就不符合题意了。那么什么样的根节点才是最好的呢?链表的中间节点!如果链表的长度是奇数那么让中间节点来当根节点的话左右子树的高度就是相同的,如果链表的长度是偶数那么左右子树的高度也只是差1而已刚好符合平衡二叉搜索树的定义。想要找到链表的中间节点我们可以使用快慢指针的方法,在找到中间节点后我们就可以使用相同的方法来构建左子树和右子树。
代码
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
ListNode* getMid(ListNode* left,ListNode* right)
{
ListNode* fast = left;
ListNode* slow = left;
while(fast != right && fast->next != right)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
TreeNode* buildTree(ListNode* left,ListNode* right)
{
if(left == right)
{
return nullptr;
}
TreeNode* root = new TreeNode();
//获得中间节点
ListNode* mid = getMid(left,right);
root->val = mid->val;
root->left = buildTree(left,mid);
root->right = buildTree(mid->next,right);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
return buildTree(head,nullptr);
}
};