0x08's blog

題目

給定一個 binary tree 的 root,判斷這是不是 binary search tree (BST)。

BST 的定義如下 (copy-paste)

對我來說最常見的陷阱就是個別看都是正確的,但 children 的值不符合定義 ,如 LeetCode 上的 Example 2 這樣,4, 3, 6 是合法的 BST,但如果把 root 5 考慮進來,3 就比 5 還小了。因此我們需要在不同的 stack 中傳遞比單純的 bool isBST 更多的資訊。

我想到幾個可能性:

Approach: bottom-top

func isValidBST(root *TreeNode) bool {
    isBst, _, _ := dfs(root)

    return isBst
}

// isBst, min, max
func dfs(root *TreeNode) (bool, int, int) {
    if root == nil {
        return true, math.MaxInt, math.MinInt
    }

    lBst, lMin, lMax := dfs(root.Left)
    rBst, rMin, rMax := dfs(root.Right)

    if !lBst || !rBst || lMax >= root.Val || rMin <= root.Val {
        // the value didn't matter if not BST
        return false, 0, 0
    }  

    lMin = min(lMin, root.Val)
    rMax = max(rMax, root.Val)
    return true, lMin, rMax 
}

Approach: top-bottom

另外一個作法.. 回傳多個資訊不簡單,那傳入多個參數就簡單且自然多了 😌

這樣也可以更快的 return if invalid.

func isValidBST(root *TreeNode) bool {
    return valid(root, math.MinInt, math.MaxInt)
}

func valid(root *TreeNode, low, high int) bool {
    if root == nil {
        return true
    }

    // may fail on edge case that node with min int or max int.
    if root.Val <= low || root.Val >= high {
        return false
    }

    return valid(root.Left, low, root.Val) && valid(root.Right, root.Val, high)
}