链接
https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/
耗时
解题:44 min
题解:15 min
题意
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
思路
算是 【leetcode】108. 将有序数组转换为二叉搜索树(convert-sorted-array-to-binary-search-tree)(递归)[简单] 的进阶。
依然可以应用这个思想:
根节点的值是有序数组正中间的数,这样左右子树平衡。根节点的左子树就是数组最左边到中间,右子树是中间到最右边。同样的左子树的根节点的值应该是数组最左边到中间这段区间正中间的值,右子树同理。依此类推下去,直到子树所对应的数组区间中不存在元素为止。
但是 链表 和 顺序数组 的区别在于链表不能使用下标得到对应的元素,因此无法直接得到区间的中间值。使用快慢指针解决这个问题,从链表的头遍历到尾,快指针每次移动两次,慢指针每次移动一次,这样当快指针移动到链表尾的时候,慢指针正好在区间中间。
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn) ,n 是链表的节点数量。
AC代码
/**
* 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* dfs(ListNode* s, ListNode* t) {
if(s == t) return nullptr;
ListNode *slow = s, *fast = s;
while(fast != t && fast->next != t) {
slow = slow->next;
fast = fast->next->next;
}
TreeNode *left = dfs(s, slow);
TreeNode *right = dfs(slow->next, t);
TreeNode *root = new TreeNode(slow->val, left, right);
return root;
}
TreeNode* sortedListToBST(ListNode* head) {
if(head == nullptr) return nullptr;
return dfs(head, nullptr);
}
};