排序列表转换为二分查找树
来源:互联网 发布:苏州餐饮软件 编辑:程序博客网 时间: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链表对于算法设计的意义是什么呢?我个人的理解:链表是树和图的基础,也可以说是一种结构简单的树或者图,而树和图能够形象的刻画现实问题,这为算法的设计提供了广阔的空间。
- 排序列表转换为二分查找树
- 排序列表转换为二分查找树
- 排序列表转换为二分查找树
- 排序列表转换为二分查找树
- 排序列表转换为二分查找树
- LintCode-排序列表转换为二分查找树
- lintcode-排序列表转换为二分查找树-106
- 题目:排序列表转换为二分查找树
- LintCode:排序列表转换为二分查找树
- lintcode,排序列表转换为二分查找树
- LintCode 106-排序列表转换为二分查找树
- lintcode 排序列表转换为二分查找树(
- LintCode 排序列表转换为二分查找树
- 排序列表转换为二分查找树-LintCode
- 排序列表转换为二分查找树-LintCode
- LINTCODE---排序列表转换为二分查找树
- 排序列表转化为二分查找树
- Java实现-排列列表转换为二分查找树
- java初学者(二)继承
- Log日志
- Android、 Button 防止快速点击问题
- Big Number
- 2016 阿里 java实习生 在线笔试
- 排序列表转换为二分查找树
- ios开发 关于在app中预览pdf,word,excel时,使用QLPreviewController还是UIWebView
- Linux--内核Uevent事件机制 与 Input子系统
- Spark-submit 时出现java.lang.ClassNotFoundException
- android 按钮的四种点击事件
- 编程语言大牛王垠:编程的智慧,带你少走弯路 [本文转载CocoaChina]
- 记一次曲折的渗透测试经历
- java并发之Lock与synchronized的区别
- 常见的错误代码