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);
}
}
}