题目描述
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1。
题解
二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:(来源维基百科)
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于或等于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)。
输入是一个有序链表,为了构造一个平衡的二叉搜索树,左右子树高度差不超过1, 只需要每一次找出中位数当做根节点,它的左边是左子树全体结点,右边是右子树全体结点。
快慢指针寻找中位数的,快指针每次挪动两次,慢指针每次挪动一次,当快指针碰到边界的时候,慢指针就指向中位数把这个中位数当做根节点,递归的调用这个构造函数,把左边构造出左子树,右边构造为右子树。
/**
* 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:
TreeNode* sortedListToBST(ListNode* head) {
if(head == NULL) return NULL;//c++中NULL为整数0,nullptr 为空指针常量,是指针类型。
if(head->next == NULL) return new TreeNode(head->val);
ListNode* slow = head;
ListNode* fast = head;
ListNode* pre = NULL;
//快指针到达链表末尾时,慢指针找到中间结点slow,pre是snow之前的节点
while(fast != NULL && fast->next != NULL){
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
pre->next = NULL;
TreeNode* root = new TreeNode(slow->val);//root为根节点
root->left = sortedListToBST(head); //从head节点到pre节点是root左子树的节点
root->right = sortedListToBST(slow->next);//从slow->next到链表的末尾是root的右子树的结点
return root;
}
};
复杂度分析
- 时间复杂度: O(nlogn),n为链表长度。
- 空间复杂度: O(nlogn)。
参考
不偏之谓中,不易之谓庸
平衡二叉树专题
C++ 2种解法。 不用断开链表
有序链表转换二叉搜索树
快慢指针 好懂python
快慢指针解决,击败了100%的用户