LeetCode151--不同的二叉搜索树(L96)、验证二叉搜索树(L98)

1、不同的二叉搜索树

//给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
//
//
//
// 示例 1:
//在这里插入图片描述
//
//输入:n = 3
//输出:5
//
//
// 示例 2:
//
//
//输入:n = 1
//输出:1
//
//
//
//
// 提示:
//
//
// 1 <= n <= 19
//
// Related Topics 树 动态规划

这里主要需要推出公式,然后直接进行计算,具体可以看光放题解:
https://leetcode-cn.com/problems/unique-binary-search-trees/solution/bu-tong-de-er-cha-sou-suo-shu-by-leetcode-solution/

public int numTrees(int n) {
        // 首先需要建立起两个概念,是长度为n,并以i为根节点的搜索树的个数F(i,n)
        // 还有长度为n的序列产生搜索树的个数G(n),很明显G(n) = F(1, n)+F(1, n)+…F(i, n)…+F(n, n)
        // 其次一个根节点有左子树和右子树,所以每个根节点的左子树的数量乘以右子树的数量就等于F(i,n)
        // 即F(i,n) = G(i-1)*G(n-i)
        // 所以有公式G(n) = G(0)*G(n-1) + G(1)*G(n-2) + …G(i-1)*G(n-i)…G(n-1)*G(0)
        // 最后考虑边界条件即G(0)=0,G(1)=1
        // 由于我们需要计算长度从0到n的序列所能产生的搜索二叉树的数量,所以需要建立一个长度为n+1的数组
        int[] G = new int[n + 1];
        G[0] = 1;
        G[1] = 1;
        for (int i = 2; i < G.length; i++) {
            for (int j = 1; j <= i; j++) {
                //用于求取每一个G中的值
                G[i] += G[j-1]*G[i-j];
            }
        }
        return G[n];
    }

2、验证二叉搜索树

//给定一个二叉树,判断其是否是一个有效的二叉搜索树。
//
// 假设一个二叉搜索树具有如下特征:
//
//
// 节点的左子树只包含小于当前节点的数。
// 节点的右子树只包含大于当前节点的数。
// 所有左子树和右子树自身必须也是二叉搜索树。
//
//
// 示例 1:
//
// 输入:
// 2
// / \
// 1 3
//输出: true
//
//
// 示例 2:
//
// 输入:
// 5
// / \
// 1 4
// / \
// 3 6
//输出: false
//解释: 输入为: [5,1,4,null,null,3,6]。
// 根节点的值为 5 ,但是其右子节点值为 4 。
//
// Related Topics 树 深度优先搜索 递归

方法一:递归
如果该二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也为二叉搜索树。所以我们在函数中设置lower和higher两个变量,前者在遍历右子树的时候替换成根节点的值,后者在遍历左子树的时候替换为根节点的值。

public boolean isValidBST(TreeNode root) {
		return isValid(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    private boolean isValid(TreeNode node, long lower, long higher){
    	if(node == null){
    		return true;
		}
    	if(node.val <= lower || node.val >= higher){
    		return false;
		}
    	return isValid(node.left, lower, node.val) && isValid(node.right, node.val, higher);
	}

方法二:中序遍历
一个二叉搜索树的中序遍历结果肯定是有序的,所以将中序遍历的结果列出来再进行遍历。

class Solution {
	List list = new ArrayList<Integer>();
    public boolean isValidBST(TreeNode root) {
		midTraverse(root);
		for (int i = 0; i < list.size()-1; i++) {
			if((int)list.get(i) >= (int)list.get(i+1)){
				return false;
			}
		}
		return true;
    }
    private void midTraverse(TreeNode node){
    	if(node == null){
    		return;
		}else{
    		midTraverse(node.left);
    		list.add(node.val);
    		midTraverse(node.right);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值