題目分析:
給定一個單鏈表,其中的元素按升序排序,將其轉換爲高度平衡的二叉搜索樹。本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1。
示例:
給定的有序鏈表: [-10, -3, 0, 5, 9],一個可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面這個高度平衡二叉搜索樹:
解題思路:
這一題繼續用【LeetCode】108. Convert Sorted Array to Binary Search Tree的思路,這裏以上一題的思路爲基礎提供兩種方法。
一、將ListNode轉化成數組,然後調用上一題的sortedArrayToBST,直接返回答案,效率比較高,也好理解。
- ListNode轉數組
if not head: return None
nums = []
while head:
nums.append(head.val)
head = head.next
2.list轉Tree
def sortedArrayToBST(nums: 'List[int]') -> TreeNode:
if nums == []: return None
mid_index = len(nums)/ 2
root = TreeNode(nums[mid_index])
root.left = sortedArrayToBST(nums[:mid_index])
root.right = sortedArrayToBST(nums[mid_index + 1:])
return root
二、調整【LeetCode】108. Convert Sorted Array to Binary Search Tree的算法,ListNode與數組的區別就是不容易找到中間節點。
- 定義快慢兩個指針
fast = slow = head
- 快指針每次向後移動兩位,慢指針每次向後移動一位,這樣當快指針移動到末尾時,滿指針正好在中間位置。
while fast.next is not tail and fast.next.next is not tail:
fast = fast.next.next
slow = slow.next
- 然後按照之前的思路遞歸
root = TreeNode(slow.val)
root.left = buildTree(head, slow)
root.right = buildTree(slow.next, tail)
提交代碼1:(轉數組遞歸,Runtime: 128 ms, faster than 89.41% )
class Solution:
def sortedListToBST(self, head: ListNode) -> TreeNode:
if not head: return None
nums = []
while head:
nums.append(head.val)
head = head.next
def sortedArrayToBST(nums: 'List[int]') -> TreeNode:
if nums == []: return None
mid_index = len(nums) // 2
root = TreeNode(nums[mid_index])
root.left = sortedArrayToBST(nums[:mid_index])
root.right = sortedArrayToBST(nums[mid_index + 1:])
return root
return sortedArrayToBST(nums)
提交代碼2:(快慢指針遞歸,Runtime: 136 ms, faster than 51.28% )
class Solution(object):
def sortedListToBST(self, head):
if not head: return
def buildTree(head, tail):
if head == tail: return
fast = slow = head
while fast.next is not tail and fast.next.next is not tail:
fast = fast.next.next
slow = slow.next
root = TreeNode(slow.val)
root.left = buildTree(head, slow)
root.right = buildTree(slow.next, tail)
return root
return buildTree(head, None)