Given an array of integers arr = [5, 6, 1]
. When we construct a BST with this input in the same order, we will have "5" as root, "6" as the right child and "1" as left child.
Now if our input is changed to [5,1,6], our BST structure will still be identical.
So given an array of integers, how to find the number of different permutations of the input array that results in the identical BST as the BST formed on the original array order?
Your question is equivalent to the question of counting the number of topological orderings for the given BST.
For example, for the BST
10
/ \
5 20
\7 | \
15 30
the set of topological orderings can be counted by hand like this: 10 starts every ordering. The number of topological orderings for the subtree starting with 20 is two: (20, 15, 30) and (20, 30, 15). The subtree starting with 5 has only one ordering: (5, 7). These two sequence can be interleaved in an arbitrary manner, leading to 2 x 10 interleavings, thus producing twenty inputs which produce the same BST. The first 10 are enumerated below for the case (20, 15, 30):
10 5 7 20 15 30
10 5 20 7 15 30
10 5 20 15 7 30
10 5 20 15 30 7
10 20 5 7 15 30
10 20 5 15 7 30
10 20 5 15 30 7
10 20 15 5 7 30
10 20 15 5 30 7
10 20 15 30 5 7
The case (20, 30, 15) is analogous --- you can check that any one of the following inputs produces the same BST.
This examples also provides a recursive rule to calculate the number of the orderings. For a leaf, the number is 1. For a non-leaf node with one child, the number equals to the number of topological orderings for the child. For a non-leaf node with two children with subtree sizes |L| and |R|, both having l and r orderings, resp., the number equals to
l x r x INT(|L|, |R|)
Where INT is the number of possible interleavings of |L| and |R| elements. This can be calculated easily by (|L| + |R|)! / (|L|! x |R|!). For the example above, we get the following recursive computation:
Ord(15) = 1
Ord(30) = 1
Ord(20) = 1 x 1 x INT(1, 1) = 2 ; INT(1, 1) = 2! / 1 = 2
Ord(7) = 1
Ord(5) = 1
Ord(10) = 1 x 2 x INT(2, 3) = 2 x 5! / (2! x 3!) = 2 x 120 / 12 = 2 x 10 = 20
This solves the problem.
Note: this solution assumes that all nodes in the BST have different keys.
Thanks for the explanation antti.huima! This helped me understand. Here is some C++:
#include <vector>
#include <iostream>
using namespace std;
int factorial(int x) {
return (x <= 1) ? 1 : x * factorial(x - 1);
}
int f(int a, int b) {
return factorial(a + b) / (factorial(a) * factorial(b));
}
template <typename T>
int n(vector<T>& P) {
if (P.size() <= 1) return 1;
vector<T> L, R;
for (int i = 1; i < P.size(); i++) {
if (P[i] < P[0])
L.push_back(P[i]);
else
R.push_back(P[i]);
}
return n(L) * n(R) * f(L.size(), R.size());
}
int main(int argc, char *argv[]) {
vector<int> a = { 10, 5, 7, 20, 15, 30 };
cout << n(a) << endl;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With