📜  计算生成相同二进制搜索树(BST)的给定数组的排列

📅  最后修改于: 2021-04-22 00:53:24             🧑  作者: Mango

给定一个大小为N的数组arr [] ,该数组由范围为[1,N]的元素组成,该数组表示将元素插入到Binary Search Tree中的顺序,任务是计算重新排列方式的数量给定的数组以获得相同的BST。

例子:

方法:想法是首先修复根节点,然后递归计算重新排列左子树元素和右子树元素的方式的数量,以使左子树元素和子树元素之间的相对顺序和正确的子树必须相同。这是递归关系:

请按照以下步骤解决问题:

  1. 修复BST的根节点,并存储左子树的元素(小于arr [0]的元素),例如ctLeft [] ,并存储右子树的元素(小于arr [0]的元素) ),例如ctRight []。
  2. 要生成相同的BST,请在左子树和右子树的元素内保持相对顺序。
  3. 使用上述递归关系计算重新排列数组以生成BST的方式数。
C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to precompute the
// factorial of 1 to N
void calculateFact(int fact[], int N)
{
    fact[0] = 1;
    for (long long int i = 1; i < N; i++) {
        fact[i] = fact[i - 1] * i;
    }
}
 
// Function to get the value of nCr
int nCr(int fact[], int N, int R)
{
    if (R > N)
        return 0;
 
    // nCr= fact(n)/(fact(r)*fact(n-r))
    int res = fact[N] / fact[R];
    res /= fact[N - R];
 
    return res;
}
 
// Function to count the number of ways
// to rearrange the array to obtain same BST
int countWays(vector& arr, int fact[])
{
    // Store the size of the array
    int N = arr.size();
 
    // Base case
    if (N <= 2) {
        return 1;
    }
 
    // Store the elements of the
    // left subtree of BST
    vector leftSubTree;
 
    // Store the elements of the
    // right subtree of BST
    vector rightSubTree;
 
    // Store the root node
    int root = arr[0];
 
    for (int i = 1; i < N; i++) {
 
        // Push all the elements
        // of the left subtree
        if (arr[i] < root) {
            leftSubTree.push_back(
                arr[i]);
        }
 
        // Push all the elements
        // of the right subtree
        else {
            rightSubTree.push_back(
                arr[i]);
        }
    }
 
    // Store the size of leftSubTree
    int N1 = leftSubTree.size();
 
    // Store the size of rightSubTree
    int N2 = rightSubTree.size();
 
    // Recurrence relation
    int countLeft
        = countWays(leftSubTree,
                    fact);
    int countRight
        = countWays(rightSubTree,
                    fact);
 
    return nCr(fact, N - 1, N1)
           * countLeft * countRight;
}
 
// Driver Code
int main()
{
 
    vector arr;
    arr = { 3, 4, 5, 1, 2 };
 
    // Store the size of arr
    int N = arr.size();
 
    // Store the factorial up to N
    int fact[N];
 
    // Precompute the factorial up to N
    calculateFact(fact, N);
 
    cout << countWays(arr, fact);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to precompute the
// factorial of 1 to N
static void calculateFact(int fact[], int N)
{
    fact[0] = 1;
    for(int i = 1; i < N; i++)
    {
        fact[i] = fact[i - 1] * i;
    }
}
 
// Function to get the value of nCr
static int nCr(int fact[], int N, int R)
{
    if (R > N)
        return 0;
 
    // nCr= fact(n)/(fact(r)*fact(n-r))
    int res = fact[N] / fact[R];
    res /= fact[N - R];
 
    return res;
}
 
// Function to count the number of ways
// to rearrange the array to obtain same BST
static int countWays(Vector arr,
                     int fact[])
{
     
    // Store the size of the array
    int N = arr.size();
 
    // Base case
    if (N <= 2)
    {
        return 1;
    }
 
    // Store the elements of the
    // left subtree of BST
    Vector leftSubTree = new Vector();
 
    // Store the elements of the
    // right subtree of BST
    Vector rightSubTree = new Vector();
 
    // Store the root node
    int root = arr.get(0);
 
    for(int i = 1; i < N; i++)
    {
         
        // Push all the elements
        // of the left subtree
        if (arr.get(i) < root)
        {
            leftSubTree.add(arr.get(i));
        }
 
        // Push all the elements
        // of the right subtree
        else
        {
            rightSubTree.add(arr.get(i));
        }
    }
 
    // Store the size of leftSubTree
    int N1 = leftSubTree.size();
 
    // Store the size of rightSubTree
    int N2 = rightSubTree.size();
 
    // Recurrence relation
    int countLeft = countWays(leftSubTree,
                              fact);
    int countRight = countWays(rightSubTree,
                               fact);
 
    return nCr(fact, N - 1, N1) *
             countLeft * countRight;
}
 
// Driver Code
public static void main(String[] args)
{
    int []a = { 3, 4, 5, 1, 2 };
     
    Vector arr = new Vector();
    for(int i : a)
        arr.add(i);
         
    // Store the size of arr
    int N = a.length;
 
    // Store the factorial up to N
    int []fact = new int[N];
 
    // Precompute the factorial up to N
    calculateFact(fact, N);
 
    System.out.print(countWays(arr, fact));
}
}
 
// This code is contributed by Amit Katiyar


Python3
# Python3 program to implement
# the above approach
 
# Function to precompute the
# factorial of 1 to N
def calculateFact(fact: list, N: int) -> None:
 
    fact[0] = 1
    for i in range(1, N):
        fact[i] = fact[i - 1] * i
 
# Function to get the value of nCr
def nCr(fact: list, N: int, R: int) -> int:
 
    if (R > N):
        return 0
 
    # nCr= fact(n)/(fact(r)*fact(n-r))
    res = fact[N] // fact[R]
    res //= fact[N - R]
 
    return res
 
# Function to count the number of ways
# to rearrange the array to obtain same BST
def countWays(arr: list, fact: list) -> int:
 
    # Store the size of the array
    N = len(arr)
 
    # Base case
    if (N <= 2):
        return 1
 
    # Store the elements of the
    # left subtree of BST
    leftSubTree = []
 
    # Store the elements of the
    # right subtree of BST
    rightSubTree = []
 
    # Store the root node
    root = arr[0]
 
    for i in range(1, N):
 
        # Push all the elements
        # of the left subtree
        if (arr[i] < root):
            leftSubTree.append(arr[i])
 
        # Push all the elements
        # of the right subtree
        else:
            rightSubTree.append(arr[i])
 
    # Store the size of leftSubTree
    N1 = len(leftSubTree)
 
    # Store the size of rightSubTree
    N2 = len(rightSubTree)
 
    # Recurrence relation
    countLeft = countWays(leftSubTree, fact)
    countRight = countWays(rightSubTree, fact)
 
    return (nCr(fact, N - 1, N1) *
            countLeft * countRight)
 
# Driver Code
if __name__ == '__main__':
 
    arr = [ 3, 4, 5, 1, 2 ]
 
    # Store the size of arr
    N = len(arr)
 
    # Store the factorial up to N
    fact = [0] * N
 
    # Precompute the factorial up to N
    calculateFact(fact, N)
     
    print(countWays(arr, fact))
 
# This code is contributed by sanjeev2552


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to precompute the
// factorial of 1 to N
static void calculateFact(int []fact, int N)
{
    fact[0] = 1;
    for(int i = 1; i < N; i++)
    {
        fact[i] = fact[i - 1] * i;
    }
}
 
// Function to get the value of nCr
static int nCr(int []fact, int N, int R)
{
    if (R > N)
        return 0;
 
    // nCr= fact(n)/(fact(r)*fact(n-r))
    int res = fact[N] / fact[R];
    res /= fact[N - R];
 
    return res;
}
 
// Function to count the number of ways
// to rearrange the array to obtain same BST
static int countWays(List arr,
                     int []fact)
{
     
    // Store the size of the array
    int N = arr.Count;
 
    // Base case
    if (N <= 2)
    {
        return 1;
    }
 
    // Store the elements of the
    // left subtree of BST
    List leftSubTree = new List();
 
    // Store the elements of the
    // right subtree of BST
    List rightSubTree = new List();
 
    // Store the root node
    int root = arr[0];
 
    for(int i = 1; i < N; i++)
    {
         
        // Push all the elements
        // of the left subtree
        if (arr[i] < root)
        {
            leftSubTree.Add(arr[i]);
        }
 
        // Push all the elements
        // of the right subtree
        else
        {
            rightSubTree.Add(arr[i]);
        }
    }
 
    // Store the size of leftSubTree
    int N1 = leftSubTree.Count;
 
    // Store the size of rightSubTree
    int N2 = rightSubTree.Count;
 
    // Recurrence relation
    int countLeft = countWays(leftSubTree,
                              fact);
    int countRight = countWays(rightSubTree,
                               fact);
 
    return nCr(fact, N - 1, N1) *
             countLeft * countRight;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []a = { 3, 4, 5, 1, 2 };
     
    List arr = new List();
    foreach(int i in a)
        arr.Add(i);
         
    // Store the size of arr
    int N = a.Length;
 
    // Store the factorial up to N
    int []fact = new int[N];
 
    // Precompute the factorial up to N
    calculateFact(fact, N);
 
    Console.Write(countWays(arr, fact));
}
}
 
// This code is contributed by Amit Katiyar


输出:
6







时间复杂度: O(N 2 )
辅助空间: O(N)