题目描述
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
解题思路
这道题和“将有序列表转换为二叉搜索树”思路是一样的。
在题目“将有序列表转换为二叉搜索树”中,我们利用列表的索引,可以方便地找到列表的中点(当列表长度为偶数时,此处默认后一个为中点),并利用列表的切片索引,递归的构建搜索二叉树的左右子树(中点左边的作为左子树的列表输入,中点右边的列表作为右子树的列表输入),代码1 中将给出实现“有序列表转换为二叉搜索树”的实现。
依照上述思路,将一个有序链表转换为二叉搜索树,需要找出链表的中间节点,并将链表分为左右链表,分别作为左子树的链表输入和右子树的链表输入。
找出链表的中间节点可以利用快慢指针来完成,即快指针每次走两步,慢指针每次走一步,当快指针走到链表结尾时,慢指针指向链表的中点。
思路2:当然,解此题也可以将链表转换为列表之后再转换为二叉搜索树,这样需要额外的空间。
代码1:有序列表转换为二叉搜索树
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if not nums:
return None
mid = len(nums)//2
node = TreeNode(nums[mid])
node.left = self.sortedArrayToBST(nums[:mid])
node.right = self.sortedArrayToBST(nums[mid+1:])
return node
代码2:有序链表转换为二叉搜索树
class Solution:
def findMidNode(self, head):
if not head:
return None
fast, slow = head, head
pre = None
while fast and fast.next:
pre = slow
slow = slow.next
fast = fast.next.next
if pre: # 将中间节点的上一个节点指向None,即将原链表在中间节点处拆开
pre.next = None
return slow
def sortedListToBST(self, head: ListNode) -> TreeNode:
if not head:
return None
mid = self.findMidNode(head) # 调用后原链表被拆开
node = TreeNode(mid.val)
if mid == head:
return node
node.left = self.sortedListToBST(head)
node.right = self.sortedListToBST(mid.next)
return node
代码3:链表转换为列表思路
class Solution:
def sortedListToBST(self, head: ListNode) -> TreeNode:
def link2List(head):
vals = []
while head:
vals.append(head.val)
head = head.next
return vals
if not head:
return None
linkList = link2List(head)
def helper(left, right):
if left > right:
return None
mid = (left + right + 1)//2
root = TreeNode(linkList[mid])
root.left = helper(left, mid - 1)
root.right = helper(mid + 1, right)
return root
return helper(0, len(linkList) - 1)