[LeetCode]109. 有序链表转换二叉搜索树
109. 有序链表转换二叉搜索树
回溯
这里比较难的点在于,如何去区分左子树和右子树,因为不可能像数组那样简单的分片操作,那么可以使用变量标记起始和终点即可。
class Solution(object):
def sortedListToBST(self, head):
"""
:type head: ListNode
:rtype: TreeNode
"""
def backtracking(start, end):
if start == end:
return None
slow, fast = start, start
while fast != end and fast.next != end:
slow = slow.next
fast = fast.next.next
cur = TreeNode(slow.val)
cur.left = backtracking(start, slow)
cur.right = backtracking(slow.next, end)
return cur
if not head:
return None
return backtracking(head, None)
或者把回调函数提取出来:
class Solution(object):
def sortedListToBST(self, head):
"""
:type head: ListNode
:rtype: TreeNode
"""
if not head:
return None
if not head.next:
# 不能直接返回head,因为这里是树结点而非链表节点
return TreeNode(head.val)
# 通过find_root函数返回的是右边链表的起始节点
right_root = self.find_root(head)
# 以该节点作为起始节点
root = TreeNode(right_root.val)
# 在find_root函数中已经将head进行了切分,因此这里的head则是不断被切分的左边链表的起始节点
root.left = self.sortedListToBST(head)
root.right = self.sortedListToBST(right_root.next)
return root
def find_root(self, head):
"""
找出中间节点(右边链表的起点)返回,并且把左边链表和右边链表进行切分
"""
prev, slow, fast = head, head, head
while fast and fast.next:
prev = slow
slow = slow.next
fast = fast.next.next
prev.next = None
return slow
然后也可以将链表转化成数组,变成控制数组的左右区间,然后再进行操作:
# convert linked list to array
def sortedListToBST1(self, head):
ls = []
while head:
ls.append(head.val)
head = head.next
return self.helper(ls, 0, len(ls)-1)
def helper(self, ls, start, end):
if start > end:
return None
if start == end:
return TreeNode(ls[start])
mid = (start+end) >> 1
root = TreeNode(ls[mid])
root.left = self.helper(ls, start, mid-1)
root.right = self.helper(ls, mid+1, end)
return root

关注公众号:数据结构与算法那些事儿,每天一篇数据结构与算法