美文网首页算法学习
算法题--将升序排列的链表转化为一棵二叉搜索树

算法题--将升序排列的链表转化为一棵二叉搜索树

作者: 岁月如歌2020 | 来源:发表于2020-04-29 16:13 被阅读0次
    image.png

    0. 链接

    题目链接

    1. 题目

    Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

    Example:

    Given the sorted linked list: [-10,-3,0,5,9],

    One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:

          0
         / \
       -3   9
       /   /
     -10  5
    

    2. 思路1: 先转化为数组, 再按照取中心点作为根节点的方法递归构造

    时间复杂度O(N)
    空间复杂度O(N)

    3. 代码

    
    # Convert the given linked list to an array
    def mapListToValues(self, head):
        vals = []
        while head:
            vals.append(head.val)
            head = head.next
        return vals    
    
    def sortedListToBST(self, head):
        """
        :type head: ListNode
        :rtype: TreeNode
        """
    
        # Form an array out of the given linked list and then
        # use the array to form the BST.
        values = self.mapListToValues(head)
    
        # l and r represent the start and end of the given array
        def convertListToBST(l, r):
    
            # Invalid case
            if l > r:
                return None
    
            # Middle element forms the root.
            mid = (l + r) // 2
            node = TreeNode(values[mid])
    
            # Base case for when there is only one element left in the array
            if l == r:
                return node
    
            # Recursively form BST on the two halves
            node.left = convertListToBST(l, mid - 1)
            node.right = convertListToBST(mid + 1, r)
            return node
        return convertListToBST(0, len(values) - 1)
    
    def print_tree(root):
        array = list()
    
        def preorder_traverse(node):
            array.append(node.val)
            if node.left is not None:
                preorder_traverse(node.left)
            else:
                array.append(None)
            if node.right is not None:
                preorder_traverse(node.right)
            else:
                array.append(None)
    
        if root is not None:
            preorder_traverse(root)
        print(array)
    
    
    solution = Solution()
    head = node = ListNode(-10)
    node.next = ListNode(-3)
    node = node.next
    node.next = ListNode(0)
    node = node.next
    node.next = ListNode(5)
    node = node.next
    node.next = ListNode(9)
    node = node.next
    
    print_tree(solution.sortedListToBST(head))
    
    

    输出结果

    [0, -10, None, -3, None, None, 5, None, 9, None, None]
    

    4. 结果

    image.png

    5. 思路2: 先算出元素数量+再使用递归

    • 先遍历一次链表, 计算出元素数量size
    • 再按照中序遍历的思路, 进行递归调用
    def 处理一棵树(l, r):
        处理左子树[l, mid - 1]
        从链表中取出一个值作为当前根节点
        处理右子树[mid + 1, l]
    

    可以看出, 按照这样的步骤, 左下角的那个节点, 首次取出链表头部元素, 然后其父节点再取第二个元素, 其右兄弟节点取出第三个元素, 这样一个子树构建完成; 按照这样的构建思路, 逐渐从左下角到中间到右下角,逐渐构造完一棵树

    这个递归方法一共被调用logN次, 意味着计算过程中分配的空间复杂度为O(logN)

    6. 代码

    class Solution1:
        def sortedListToBST(self, head: ListNode) -> TreeNode:
    
            def convert(l, r):
                nonlocal head
    
                if l > r:
                    return None
                mid = l + (r - l) // 2
                left = convert(l, mid - 1)
                node = TreeNode(head.val)
                head = head.next
                node.left = left
                node.right = convert(mid + 1, r)
    
                return node
    
            size = 0
            each_node = head
            while each_node is not None:
                size += 1
                each_node = each_node.next
    
            return convert(0, size - 1)
    
    
    def print_tree(root):
        array = list()
    
        def preorder_traverse(node):
            array.append(node.val)
            if node.left is not None:
                preorder_traverse(node.left)
            else:
                array.append(None)
            if node.right is not None:
                preorder_traverse(node.right)
            else:
                array.append(None)
    
        if root is not None:
            preorder_traverse(root)
        print(array)
    
    
    solution = Solution1()
    head = node = ListNode(-10)
    node.next = ListNode(-3)
    node = node.next
    node.next = ListNode(0)
    node = node.next
    node.next = ListNode(5)
    node = node.next
    node.next = ListNode(9)
    node = node.next
    
    print_tree(solution.sortedListToBST(head))
    

    输出结果为

    [0, -10, None, -3, None, None, 5, None, 9, None, None]
    

    7. 结果

    image.png

    相关文章

      网友评论

        本文标题:算法题--将升序排列的链表转化为一棵二叉搜索树

        本文链接:https://www.haomeiwen.com/subject/ttknwhtx.html