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

https://leetcode-cn.com/problems/number-of-ways-to-reorder-array-to-get-same-bst/

 组合+递归

1.按照特定顺序插入,第一个节点就是根节点,后面的插入的都在根节点下面,所以无论怎么排序,第一个总是不变的。

2.后面的可以分成两半,小于根节点的和大于根节点的,这两个集合互不影响,都是分别往根节点左边或根节点右边插入,所以只用考虑一个集合内的相对顺序。

3.考虑左集合或右集合,就是递归了

4.首先从后面的位置(左集合数量+右集合数量)中选出左节点集合的位置,是一个组合数,然后看左集合有多少种方法(这是个递归),以及右集合有多少种方法(也是个递归),再乘起来(因为是步骤型的),初始条件,如果只有一个节点,排列方法只有1种

5.确定了左右子集的数量,并不能确定结果,因为是递归调用,还要根据左(右)子集的左右子集数量来确定

 

class Solution {
public:
    long long mod=1e9 + 7;
    long long c_record[1005][1005];

    long long c(int n,int m){
        if(c_record[n][m]!=-1)
            return c_record[n][m];
        if(m==0)
            return 1;
        if(n==m)
            return 1;
        if(n==1)
            return 1;
        if(m==1){
            return n;
        }
        
        long long ret= (c(n-1,m-1)+c(n-1,m))%mod;
        c_record[n][m]=ret;
        return ret;
        
    }

    long long fun(vector<int> &nums){
        if(nums.size()==0)
            return 1;
        vector<int> left;
        vector<int> right;
        int root_val=nums[0];
        
        for(int i=1;i<nums.size();i++){
            if(nums[i]<root_val)
                left.push_back(nums[i]);
            else if(nums[i]>root_val)
                right.push_back(nums[i]);
        }
     
            

        int size=left.size()+right.size();
        long long select_num=c(size,left.size());
        long long ret= ((( select_num * fun(left))%mod) * fun(right))%mod;
        return ret;
    }

    int numOfWays(vector<int>& nums) {
        memset(c_record,-1,sizeof(c_record));

        return (fun(nums)-1+mod)%mod;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值