Loading

力扣 - 109. 有序链表转换为二叉搜索树

题目

109. 有序链表转换二叉搜索树

思路1(分治+前序)

  • 二叉搜索树就是左孩子比根节点小,右孩子比根节点大,而且左右两个子树的高度差不大于1称为二叉搜索树
  • 通过观察这个链表转换成的搜索树可以发现,根节点其实就是链表的中间的结点,左孩子就是左边一半链表的中间的结点,右孩子就是右边一半链表的中间的结点
  • 所以可以利用递归(自顶向下)方法来解题,递归的截止条件就是遍历到本段链表末尾

代码

class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if (head == null) {
            return null;
        }
        if (head.next == null) {
            return new TreeNode(head.val);
        }

        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null;
        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.left = sortedListToBST(head);
        root.right = sortedListToBST(slow.next);

        return root;
    }
}

复杂度分析

  • 时间复杂度:\(O(NlogN)\),其中 N 为链表的长度。
  • 空间复杂度:\(O(logN)\),其中logN为树的深度,递归时所创建的空间

思路2(分治+中序)

  • 我们只需要在分治的过程中不断进行分治,直到left>right,且在这过程中不需要找出链表的中位结点,而是先用一个空值的节点栈为构建一颗二叉树雏形
  • 等到中序遍历遍历到该结点时,再进行值的填充
  • 因为链表的结果是升序的,而二叉搜索树的中序遍历也是升序的,所以globalHead = globalHead.next就可以有序地填充树的节点的值

代码

class Solution {
    ListNode globalHead;
    public TreeNode sortedListToBST(ListNode head) {
        globalHead = head;
        // 获取链表长度
        int length = 0;
        while (head != null) {
            length++;
            head = head.next;
        }
        // 进行递归中序遍历构建树
        return inorderBuild(0, length-1);
    }

    public TreeNode inorderBuild(int left, int right) {
        if (left > right) {
            return null;
        }

        // 获取中位数
        int mid = (left + right + 1) / 2;
        // 先构建空值的节点占位
        TreeNode root = new TreeNode();

        // 左子树遍历
        root.left = inorderBuild(left, mid - 1);
        // 进行节点的填充
        root.val = globalHead.val;
        globalHead = globalHead.next;
        // 右子树遍历
        root.right = inorderBuild(mid + 1, right);

        return root;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),其中 N 是链表长度
  • 空间复杂度:\(O(logN)\)
posted @ 2020-11-10 07:44  linzeliang  阅读(73)  评论(0)    收藏  举报