前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >LeetCode 1569. 将子数组重新排序得到同一个二叉查找树的方案数(DP)

LeetCode 1569. 将子数组重新排序得到同一个二叉查找树的方案数(DP)

作者头像
Michael阿明
发布2021-02-19 14:21:18
发布2021-02-19 14:21:18
44500
代码可运行
举报
运行总次数:0
代码可运行

文章目录

1. 题目

给你一个数组 nums 表示 1 到 n 的一个排列。 我们按照元素在 nums 中的顺序依次插入一个初始为空的二叉查找树(BST)。 请你统计将 nums 重新排序后,统计满足如下条件的方案数:重排后得到的二叉查找树与 nums 原本数字顺序得到的二叉查找树相同。

比方说,给你 nums = [2,1,3],我们得到一棵 2 为根,1 为左孩子,3 为右孩子的树。 数组 [2,3,1] 也能得到相同的 BST,但 [3,2,1] 会得到一棵不同的 BST 。

请你返回重排 nums 后,与原数组 nums 得到相同二叉查找树的方案数

由于答案可能会很大,请将结果对 10^9 + 7 取余数。

示例 1:

代码语言:javascript
代码运行次数:0
复制
输入:nums = [2,1,3]
输出:1
解释:我们将 nums 重排, [2,3,1] 能得到相同的 BST 。
没有其他得到相同 BST 的方案了。

示例 2:

代码语言:javascript
代码运行次数:0
复制
输入:nums = [3,4,5,1,2]
输出:5
解释:下面 5 个数组会得到相同的 BST:
[3,1,2,4,5]
[3,1,4,2,5]
[3,1,4,5,2]
[3,4,1,2,5]
[3,4,1,5,2]

示例 3:

代码语言:javascript
代码运行次数:0
复制
输入:nums = [1,2,3]
输出:0
解释:没有别的排列顺序能得到相同的 BST 。

示例 4:

代码语言:javascript
代码运行次数:0
复制
输入:nums = [3,1,2,5,4,6]
输出:19

示例  5:
输入:nums = [9,4,2,1,3,6,5,7,8,14,11,10,12,13,16,15,17,18]
输出:216212978
解释:得到相同 BST 的方案数是 3216212999。
将它对 10^9 + 7 取余后得到 216212978。
 
提示:
1 <= nums.length <= 1000
1 <= nums[i] <= nums.length
nums 中所有数 互不相同 。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/number-of-ways-to-reorder-array-to-get-same-bst 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 根节点是数组第一个数
  • 然后分为左右两个子树,左右子树之间的顺序不乱就可以
  • 假设左子树 L 长度 nL,右子树 R 长度 nR,存在方案数为 CnL+nRnL​∗f(L)∗f(R)
代码语言:javascript
代码运行次数:0
复制
class Solution {
	vector<vector<int>> C;
	int mod = 1e9+7;
public:
    int numOfWays(vector<int>& nums) {
    	int n = nums.size();
    	C = vector<vector<int>> (n+1, vector<int>(n+1, 0));
    	C[1][0] = 1, C[1][1] = 1;
    	// DP 求解组合数
    	for(int i = 2, j; i <= n; ++i)
    	{
    		for(j = 0; j <= i; ++j)
    		{
    			if(j==0 || j==i)
    				C[i][j] = 1;
    			else
    			{
    				C[i][j] = (C[i-1][j-1] + C[i-1][j])%mod;
    			}
    		}
    	}
    	return (dfs(nums)-1)%mod;
    }
    long long dfs(vector<int> &nums)
    {
    	if(nums.size() <= 1)
    		return 1;
    	int root = nums[0], n = nums.size();
    	vector<int> l, r;
    	for(int num : nums)
    	{
    		if(num < root)
    			l.push_back(num);
    		else if(num > root)
    			r.push_back(num);
    	}
    	long long nL = dfs(l), nR = dfs(r);
    	return (((C[n-1][l.size()]*nL)%mod)*nR)%mod;
    }
};

424 ms 172.5 MB

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/08/30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档