Leetcode 109、有序链表转换二叉搜索树
思路:递归
- 题目要求有序链表转成平衡的二叉搜索树,类似于有序数组转二叉搜索树
- 思路都是:找到链表/数组的中间节点,作为当前子树的根节点,链表/数组左侧是当前根节点的左子树,链表/数组右侧是当前根节点的右子树
- 求子树的时候调用当前递归算法
- 最后返回root
- 因为每一次找的都是中间节点为当前根节点,所以可以保证是平衡的
时间复杂度
- N个节点的链表构造二叉搜索树的空间是T(n) = 2 * T(n / 2) + O(n), T(n) = O(nlogn)
空间复杂度
- 递归需要的栈空间为O(logn)
完整代码
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if(head == null) return null;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = head, fast = head;
while(fast.next != null) {
if(fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
dummy = dummy.next;
}else {
break;
}
}
/**
因为找到中间节点以后,左边的链表需要和中间链表断开,
dummy是slow的前一个节点,并且在进行左子树构建的时候,
因为里面传递的参数是head,如果slow == head的话,
那么就会陷入死循环,所以只有slow != head 的时候,
再使用递归进行左子树的构建
同理构建右子树的时候,是使用当前中间节点的右半部分,所以使用next
**/
dummy.next = null;
TreeNode root = new TreeNode(slow.val);
if(head != slow) {
root.left = sortedListToBST(head);
}
root.right = sortedListToBST(slow.next);
return root;
}
}