二叉搜索树

每个节点比它左子树的任意节点大,而且比它右子树的任意节点小

98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:
    2
   / \
  1   3
输出: true

示例 2:

输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4 。
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        if not root:
            return True
        stack = [(root,float('-inf'),float('inf'))]
        while stack:
            node,lower,upper = stack.pop()
            if not node:
                continue
            val = node.val
            if val <= lower or val >= upper:
                return False
            stack.append((node.right,val,upper))
            stack.append((node.left,lower,val))
        return True
#借用中序遍历,左根右 且大小依次增加
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        if not root:
            return True
        stack = []
        pre = float('-inf')
        while stack or root:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            val = root.val
            if val <= pre:
                return False
            pre = val
            root = root.right
        return True

96. 不同的二叉搜索树

给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

示例:

输入: 3
输出: 5
解释:
给定 n = 3, 一共有 5 种不同结构的二叉搜索树:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

思路

动态规划

问题是计算不同二叉搜索树的个数。为此,我们可以定义两个函数:

  • \(G(n)\): 长度为n的序列的不同二叉搜索树个数。

  • \(F(i, n)\): 以i为根的不同二叉搜索树个数

以序列中每个节点 \(i\) 作为根节点,遍历:

是对遍历所有 i (1 <= i <= n) 的 F(i, n)F(i,n) 之和。换而言之:

\[G(n) = \sum_{i=1}^{n} F(i, n) \]

对边界情况,当序列长度为 1 (只有根)或为 0 (空树)时,只有一种情况。亦即:

\[G(0)=1,G(1)=1 \]

给定序列 \(1 ... n\),我们选出数字 \(i\) 作为根,则对于根 \(i\) 的不同二叉搜索树数量 \(F(i, n)\), 是左右子树个数的组合,如下图所示:

得到:

\[F(i,n)=G(i−1)⋅G(n−i)\\G(n)= \sum_{i=1}^n G(i−1)⋅G(n−i) \]

class Solution:
    def numTrees(self, n: int) -> int:
        #动态规划
        G = [0]*(n+1)
        G[0] = G[1] = 1
        for i in range(2,n+1):
            for j in range(1,i+1):
                G[i] += G[j-1]*G[i-j]
        return G[n]
posted @ 2020-04-18 14:31  鱼与鱼  阅读(130)  评论(0编辑  收藏  举报