Convert Sorted List to Binary Search Tree

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

看到这题我想到的直接的做法是每次找到链表的中间结点(slow 和 fast双指针屡试不爽),递归构建左子树和右子树。 但是注意这里需要分割左子树,则需要将左子序列的尾结点的next置为None,否则又会出现环。所以这种情况下,每次找到中序结点的前一个结点更明智。当然如果只有一个或者两个结点,只能找到头结点,所以需要判断。这种做法避免了再开一个指针来做尾结点的处理。这种每次处理都需要花费O(n)的时间复杂度来寻找中间结点,所以时间复杂度为O(nlogn),空间复杂度也为O(nlogn),代码如下:

class Solution(object):
    def sortedListToBST(self, head):
        """
        :type head: ListNode
        :rtype: TreeNode
        """
        if not head:
            return None
        if not head.next:
            return TreeNode(head.val)
 
        slow = head
        fast = head.next
        while fast.next and fast.next.next:
            fast = fast.next.next
            slow = slow.next
        if slow == head and not slow.next.next: #判断是不是只有两个节点的情况
            root = TreeNode(slow.val)
            root.right = self.sortedListToBST(slow.next) #此时只有右子树
        else:
            root = TreeNode(slow.next.val)
            tmp = slow.next
            slow.next = None
            root.left = self.sortedListToBST(head)
            root.right = self.sortedListToBST(tmp.next)
        return root

以上解法是top down,如果采取bottom up的做法,可以将时间复杂度降为O(n)。看了一下bottom up的做法都参考自一个leetcode的链接:http://articles.leetcode.com/convert-sorted-list-to-balanced-binary 这种做法每次在递归的时候会改头结点。所以当返回时建立的树结点就是当前的子树的根结点。代码如下:

class Solution(object):
    def sortedListToBST(self, head):
        """
        :type head: ListNode
        :rtype: TreeNode
        """
        if not head:
            return None
        cur = head
        n = 0
        while cur:
            cur = cur.next
            n += 1
        return self.helper([head], 0, n-1)
        
    def helper(self, head, start, end):
        if start > end:
            return None
        mid = start + (end - start)/2
        left = self.helper(head, start, mid-1)
        parent = TreeNode(head[0].val)
        head[0] = head[0].next
        parent.left = left
        parent.right = self.helper(head, mid+1, end)
        
        return parent

这段代码还没有理解的特别透彻,但是为了使输入的头结点可以更改,需要使用list来传递参数。

posted on 2016-05-31 22:23  Sheryl Wang  阅读(143)  评论(0编辑  收藏  举报

导航