LeetCode: 98.驗證二叉搜索樹

題目

給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。

假設一個二叉搜索樹具有如下特徵:

節點的左子樹只包含小於當前節點的數。
節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜索樹。

  • 就是看一顆是是否滿足二叉搜索樹。

思路

  • 劍指裏面有一道是判斷一個序列是否是某二叉搜索樹的中續遍歷。一種簡單的思路就是先中續遍歷一遍,然後用劍指的辦法判斷。

  • 但經驗告訴我,如果該樹是二叉搜索樹,我們需要走完所有的節點才能確定。但一旦某個節點不滿足二叉搜索子樹,我們是直接能得出整棵樹都不是二叉搜索樹。也就是提前阻斷法,對於不是二叉搜索樹的情況下,不必走完所有節點。比第一種辦法的效率更加高。

  • 具體做法是。採用後續遍歷,在遞歸中,判斷該節點爲根節點的子樹是否是二叉搜索樹。如果是,則返回True,該子樹的最大值,該子樹的最小值

  • 如何判斷子樹是否是二叉搜索樹?如果對左子樹遍歷得到的flag爲True,且當前節點值大於等於(不允許有重複節點)左子樹的最大值,則左分支沒問題;同理判斷右分支。

  • 最後結合當前節點的值,重新計算最小值和最大值

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def walk(p):
            if not p:
                return True, -float('inf'), float('inf')
            val = p.val
            left, max_val_1, min_val_1 = walk(p.left)
            if not left or val <= max_val_1:  # 小於等於,等於不能缺少
                return False, 0, 0
            
            right, max_val_2, min_val_2 = walk(p.right)

            if not right or val >=min_val_2:
                return False, 0, 0
            max_val = max(val, max_val_1, max_val_2)
            min_val = min(val, min_val_1, min_val_2)
            return True, max_val, min_val
        flag, _, _ = walk(root)
        return flag        

其他方法

原來先序遍歷和中序遍歷都能提前阻斷。
自己看了題解,寫了一種中序遍歷的思路,就是用path記錄中序遍歷的結果,當前節點和之前的節點比較大小。

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        path = []
        def walk(p):
            nonlocal path
            if not p:
                return True
            flag = walk(p.left)
            if not flag:
                return False
            if len(path) == 0:
                path.append(p.val)
            else:
                if path[-1] < p.val:
                    path.append(p.val)
                else:
                    return False
            flag = walk(p.right)
            return flag
        flag = walk(root)
        return flag
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章