↓快轉到主要內容
  1. LeetCode/

LeetCode 109: Convert Sorted List to Binary Search Tree

·1 分鐘· ·
LeetCode Medium Linked-List Divide-and-Conquer Tree Binary-Search-Tree
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-11-19

  • 提交紀錄:Wrong Answer ×2 → Runtime Error ×3 → Accepted ×4

解題思路
#

平衡的 BST 根要在中間(Linked List 模板三):

  1. 快慢指針找到中點,並記住中點的前一個節點,把左半邊切斷。
  2. 中點當根,左半邊、右半邊各自遞迴。

每層都從中間切,左右兩邊的大小差最多 1,所以高度平衡。

我的嘗試
#

前兩版想用兩個指標從中間同時往左右長樹,但兩邊長度不一樣時用 TreeNode(None) 補空節點,結果多了值是 None 的節點,例如 [1, 3] 中序是 [1, 3, None]。之後改成遞迴切半才 AC。

正確解法
#

class Solution:
    def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
        if not head:
            return None
        if not head.next:
            return TreeNode(head.val)
        prev, slow, fast = None, head, head
        while fast and fast.next:
            prev, slow, fast = slow, slow.next, fast.next.next
        prev.next = None                           # 切斷左半邊
        return TreeNode(slow.val, self.sortedListToBST(head), self.sortedListToBST(slow.next))

複雜度
#

時間 O(n log n)(每層找中點共 O(n)),空間 O(log n)。先轉成陣列可以做到 O(n) 時間。

要特別避免的錯誤
#

  • 要記住中點的前一個節點,才能把左半邊切斷。
  • 只剩一個節點時直接回傳,不然左半邊切不開。

面試口說整理
#

我用快慢指針找到中點當根,把左半邊從中點前面切斷,左右兩半遞迴建子樹。每次都從中間切,所以高度平衡。時間 O(n log n)。

相關文章

LeetCode 116: Populating Next Right Pointers in Each Node
·1 分鐘
LeetCode Medium Linked-List Tree Depth-First-Search Breadth-First-Search
LeetCode 116 解題筆記:完美二元樹,用上一層已經接好的 next 走過這一層:left.next = right,right.next = next.left;O(1) 額外空間
LeetCode 148: Sort List
·1 分鐘
LeetCode Medium Linked-List Two-Pointers Divide-and-Conquer Sorting
LeetCode 148 解題筆記:用快慢指針切成兩半,遞迴排序後合併;O(n log n),不需要額外陣列
LeetCode 106: Construct Binary Tree from Inorder and Postorder Traversal
·1 分鐘
LeetCode Medium Array Hash-Table Divide-and-Conquer Tree
LeetCode 106 解題筆記:後序的最後一個是根;從後序尾巴往前取根時,要先建右子樹再建左子樹
LeetCode 105: Construct Binary Tree from Preorder and Inorder Traversal
·1 分鐘
LeetCode Medium Array Hash-Table Divide-and-Conquer Tree
LeetCode 105 解題筆記:前序的第一個是根,在中序裡找到根的位置就知道左子樹有幾個節點;用字典查位置,O(n)
LeetCode 230: Kth Smallest Element in a BST
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 230 解題筆記:BST 的中序遍歷是由小到大,迭代中序走到第 k 個就停
LeetCode 98: Validate Binary Search Tree
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 98 解題筆記:每個節點都有一個合法範圍(下界, 上界),往左走上界變成自己、往右走下界變成自己;只比父子不夠