给定一个大小为N的数组arr[]由范围[1, N] 中的元素组成,该数组表示将元素插入二叉搜索树的顺序,任务是计算重新排列的方式的数量给定数组以获得相同的 BST。
例子:
Input: arr[ ] ={3, 4, 5, 1, 2}
Output: 6
Explanation :
The permutations of the array which represent the same BST are:{{3, 4, 5, 1, 2}, {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}}. Therefore, the output is 6.
Input: arr[ ] ={2, 1, 6, 5, 4, 3}
Output: 5
做法:思路是先固定根节点,然后递归计算左子树元素和右子树元素重新排列的方式的数量,使得左子树元素内的相对顺序和右子树必须相同。这是递归关系:
countWays(arr) = countWays(left) * countWays(right) * combinations(N, X).
left: Contains all the elements in the left subtree(Elements which are lesser than the root)
right: Contains all the elements in the right subtree(Elements which are greater than the root)
N = Total number of elements in arr[]
X = Total number of elements in left subtree.
请按照以下步骤解决问题:
- 固定 BST 的根节点,并存储左子树的元素(小于 arr[0] 的元素),比如ctLeft[] ,并存储右子树的元素(小于 arr[0] 的元素) ),说ctRight[]。
- 要生成相同的 BST,请保持左子树和右子树元素内的相对顺序。
- 使用上述递推关系计算重新排列数组以生成 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
Javascript
6
时间复杂度: O(N 2 )
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live