zoukankan      html  css  js  c++  java
  • 二叉搜索树

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

    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]
    
  • 相关阅读:
    纪中集训 Day 2
    纪中集训 Day1
    纪中集训 Day 0?
    BZOJ 1033: [ZJOI2008]杀蚂蚁antbuster(模拟)
    BZOJ 3527: [Zjoi2014]力(FFT)
    wikioi 3132 高精度乘法(FFT)
    BZOJ 1085: [SCOI2005]骑士精神(A*算法)
    BZOJ 1009 :[HNOI2008]GT考试(KPM算法+dp+矩阵快速幂)
    BZOJ 1019 :[SHOI2008]汉诺塔(递推)
    BZOJ 1021 :[SHOI2008]Debt 循环的债务 (DP)
  • 原文地址:https://www.cnblogs.com/gongyanzh/p/12725810.html
Copyright © 2011-2022 走看看