1. 程式人生 > >把排序陣列轉換為高度最小的二叉搜尋樹

把排序陣列轉換為高度最小的二叉搜尋樹

題目描述:給一個排序陣列(從小到大),將其轉換為一棵高度最小的二叉搜尋樹。

樣例:給出陣列 [1,2,3,4,5,6,7], 返回


首先,先來看一下二叉搜尋樹(也稱為二叉排序樹)的定義:它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別為二叉排序樹。

這麼一看,建樹的思路就很明確了。因為我們現在拿到的是一個排序陣列,那麼首先應該找的是這個陣列的中值,找的方法很容易想到之前“二分查詢”(詳見:點選開啟連結)中常用的left和right兩個指標的套路。將這個中值賦值給根節點,這個時候,顯然中值以左的資料就都比中值小了,可以用這段陣列構建根節點的左子樹,中值以右的資料都比中值大,則用來構建右子樹,構建的方法與剛才講的一樣(再分別找中值即可),這是典型的遞迴思路。

拿這個例子看一下:

1. 找到中值4,生成根節點,陣列被分成[1, 2, 3], [5, 6, 7]兩段

2. 對[1, 2, 3], [5, 6, 7]兩段分別找中值,找到了2和6,生成根節點的左右孩子。。。以此類推

需要注意的是:遞迴“觸底”的條件是陣列為空

對於這種牽涉陣列首尾位置的運算,最好能令首尾位置作為形參參與運算。例如之前我們見到的“搜尋區間”的問題(詳見:點選開啟連結)就是在求左右兩側的界限時,將陣列一分為二,分別令首尾位置作為形參。這是一種標準的解決辦法!

那麼,這道題就不難了,也採取定義新的輔助函式的方法,將首尾位置作為形參。程式碼如下:

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""
class Solution:
    """
    @param A: a list of integer
    @return: a tree node
    """
    def sortedArrayToBST(self, A):
        if len(A) == 0:
            return None
        left, right = 0, len(A) - 1
        return self.helper(A, left, right)
        
        
    def helper(self, A, left, right):
        if left <= right:
            mid = (left + right) // 2
            root = TreeNode(A[mid])
            root.left = self.helper(A, left, mid - 1)
            root.right = self.helper(A, mid + 1, right)
        else:
            return None
        return root
        # write your code here
輔助函式的“觸底”條件是left > right,也就是說這部分陣列已經處理完畢了