排序列表转换为二分查找树

来源:互联网 发布:苏州餐饮软件 编辑:程序博客网 时间:2024/06/05 07:14

题目描述:给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树

我们之前做过一道将排序数组转换为二分查找树的问题,详见:点击打开链接

将链表转换为二分查找树与上面这道题的基本思想一模一样(在这里,高度平衡,也就是高度最小),所以我们要解决的问题就是查找到排序链表的中值,作为根节点,然后将链表分割,分别按照同样的思想生成左右子树。(如果对这个算法有疑问,请先搞懂我刚才给出的链接的那道题)

那么如何查找链表的中值呢?当然不能全遍历一遍,再回溯。这方法效率太低,我在这里给出一种通用的“快慢指针法”

我假设看我这篇文章的人对链表的基本结构已经很熟悉了。那么现在可以设置两个指针slow和fast,我们令这两个指针一开始都指向链表的头结点--head,然后slow每次指向链表的下一位(就是它现在所指向的节点的next),而fast每次指向他的下一位的下一位(也就是每次向后移动两个节点),那当fast指向尾节点的时候,slow指向的刚好是中间节点。

举个例子:1->2->3->4->5

1. 一开始,slow,fast都指向1

2. slow移动一位,指2;fast移动两位,指3

3. slow接着移动一位,指3;fast接着移动两位,指5. 此时fast指向尾节点,slow刚好指向中间节点。

这是快慢指针的基本应用,当然具体处理问题的时候,快慢指针会根据具体问题做相应修改,所以,一定要灵活运用。

就拿这道题来说吧,按照上面的快慢指针法,当然能找到中间节点,但是,随后我们是要对链表分割的,而只有知道中间节点之前的那个节点,才能实现“摘链”(就是把链表的一部分“摘”下来,形成单独的链表)

所以,此处也有个通用的技巧,就是在链表的头结点之前人为的放置一个dummy节点帮助我们处理问题。还是上面的那个例子,当放置了dummy节点之后,就变成下面这个样子了:

dummy->1->2->3->4->5

可以令slow初始时指向dummy,fast初始时指向head,还是刚才那样扫描链表,发现当fast指向尾节点时,slow刚好指向2,正好在中间节点前面。我们就能实现摘链了。

所以,这个题的思路没什么值得注意的,倒是对链表的操作,是需要学习的。

代码可以给出了:

"""Definition of ListNodeclass ListNode(object):    def __init__(self, val, next=None):        self.val = val        self.next = nextDefinition of TreeNode:class TreeNode:    def __init__(self, val):        self.val = val        self.left, self.right = None, None"""class Solution:    """    @param head: The first node of linked list.    @return: a tree node    """    def sortedListToBST(self, head):        if head is None:            return None        # 随意赋值给dummy即可        dummy = TreeNode(-1)        # dummy连在head前面        dummy.next = head        slow, fast = dummy, head        # 直到fast指向尾巴        while fast and fast.next:            slow = slow.next            fast = fast.next.next        # 找到中间节点了,为slow.next        root = TreeNode(slow.next.val)        # 以下三行为摘链,需注意操作顺序        second = slow.next.next        slow.next = None        first = dummy.next        # 递归        root.left = self.sortedListToBST(first)        root.right = self.sortedListToBST(second)        return root        # write your code here
链表对于算法设计的意义是什么呢?我个人的理解:链表是树和图的基础,也可以说是一种结构简单的树或者图,而树和图能够形象的刻画现实问题,这为算法的设计提供了广阔的空间。

1 0