LeetCode 96不同的二叉搜索树&95不同的二叉搜索树Ⅱ

微信搜一搜bigsai
算法文章题解全部收录在github仓库bigsai-algorithm
关注回复进群即可加入力扣打卡群,欢迎划水。近期打卡:
LeetCode 92反转链表Ⅱ&93复制ip地址&94二叉树的中序遍历
LeetCode 90子集Ⅱ&91解码方法
LeetCode 88合并两个有序数组&89格雷编码

96 不同的二叉搜索树Ⅱ

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

示例:

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

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

分析
首先弄清这棵树是一颗二叉搜索树。大的节点只能在右侧,小的在左侧。所以n个节点如果以第i为节点,那么[1-i-1]的都在左侧,[i+1,n]都在右侧。
在这里插入图片描述

如果单单从结构上考虑那么就是:

左侧0个数量 x 右侧n-1个数量
左侧1个数量 x 右侧n-2个数量
左侧2个数量 x 右侧n-3个数量
……
左侧n-1个数量 x 右侧0个数量

所以这个题父子关系很大,从上就能得到这样的递推,当然这题我们使用动态规划来解决,dp[i]表示i个节点所有可以排列的数量。就得到状态转移方程:

dp[i]=sum(dp[j]*dp[i-j-1]) j∈[0,i) (左右子节点之和为i-1)

实现代码为:

class Solution {
    public int numTrees(int n) {
        if(n<2)return n;
        int dp[]=new int [n+1];
		 dp[0]=1;
		 dp[1]=1;
		 for(int i=2;i<n+1;i++)
		 {
			 for(int j=0;j<i;j++)
			 {
				 dp[i]+=dp[j]*dp[i-j-1];
			 }
		 }
		 return dp[n];
    }
}

95不同的二叉搜索树Ⅱ

给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。

示例:

输入:3
输出:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:

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

提示:

0 <= n <= 8

分析
这题和上一题不一样,要求我们返回所有可能的这么一个树,这题的话我还是使用递归的方式,当然不可以无脑递归然后去构造这棵树因为可能会有重复比如 2 3 1 和 2 1 3这个序列构成树的结果是一致的。
在这里插入图片描述

所以要考虑一个没有重复但能全部覆盖的策略。这题和上一题有一些不一样的地方就是上一题通过dp可能很多连续数不同但是结构相同我们可以不计算,但这里面每一种情况都需要构建。

所以这题怎么考虑呢?和上题一样,对于n个节点,我们需要考虑的其实就是n个节点每个为根节点的构造可能性。单独考虑第i个节点,第i个节点的left和right分别对应一个节点。所以要找到这种节点组合的排列可能。

在具体实现上我们借助一个递归函数generateTrees(int start, int end)表示从start到end的所有满足条件的节点。而在这个递归调用的过程中,我们循环递归分别获取根为第1,2,3……n个节点的组成情况(递归调用获取左右部分节点然后新建节点左右部分)。

具体代码为:

public List<TreeNode> generateTrees(int n) {
	   if(n==0)
		   return new ArrayList<TreeNode>();
	   return generateTrees(1,n); 
   }
private List<TreeNode> generateTrees(int start, int end) {
	// TODO Auto-generated method stub
	List<TreeNode> allList=new ArrayList<TreeNode>();//返回start-end的所有可能的节点
	if(start>end)//要有null
	{
		allList.add(null);
		return allList;
	}

	for(int i=start;i<=end;i++)
	{
		List<TreeNode>leftNodes=generateTrees(start,i-1);//左侧
		List<TreeNode>rightNodes=generateTrees(i+1,end);//右侧
		for(TreeNode lnode:leftNodes)
		{
			for(TreeNode rNode:rightNodes)//进行组合
			{
				TreeNode node=new TreeNode(i);
				node.left=lnode;
				node.right=rNode;
				allList.add(node);//创建新节点添加到集合中
			}
		}
	}
	
	return allList;
}

原创不易,bigsai请你帮两件事帮忙一下:

  1. star支持一下, 您的肯定是我在平台创作的源源动力。

  2. 微信搜索「bigsai」,关注我的公众号,不仅免费送你电子书,我还会第一时间在公众号分享知识技术。加我还可拉你进力扣打卡群一起打卡LeetCode。

记得关注、咱们下次再见!

image-20201114211553660

Big sai CSDN认证博客专家 数据结构与算法 爬虫 Java
原创公众号:「bigsai」,回复【bigsai】获取珍藏pdf书籍资源,回复【进群】即可加入leetcode打卡群。分享Java,数据结构与算法,python爬虫知识,期待和优秀的你成为朋友!
已标记关键词 清除标记
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? &nbsp; 那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的&ldquo;嵌入式&rdquo;和面向大型化的&ldquo;分布式&rdquo;开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值