Given a Preorder array of a Binary Search Tree how many other permutations of the given binary search tree will form the same BST as the given preorder.
First of a all: a value in a preorder sequence can never become an ancestor node of a node that has a value that occurred earlier in that sequence (this would be a contradiction with "preorder"). Any next value in the sequence (except the first) represents a child node of an earlier value's node. So values that are added to a tree are always leaves at the moment they are added -- never internal nodes.
The preorder sequence starts with the root, so any BST that it represents, must have it as root.
Any next value must be added as a leaf. So for the second value in the sequence there are 2 potential positions for it. For the 3rd, 3, for the 4th 4, ...etc. However, since the partial tree formed by the first k values must be a BST, there is only one of these positions for the unique (k+1)th value that is in line with the BST requirement, so there is never a choice between multiple alternatives.
By induction that means that only one BST can be formed from a preorder sequence of unique values.
Related
In Algorithms, 4th edition by Robert Sedgewick, the time complexity table for different algorithms is given as:
Based on this table, the searching time complexity of a BST is N, and of binary search in and of itself is logN.
What is the difference between the two? I have seen explanations about these separately and they made sense, however, I can't seem to understand why the searching time complexity of a BST isn't logN, as we are searching by continually breaking the tree in half and ignoring the other parts.
From binary-search-trees-bst-explained-with-examples
...on average, each comparison allows the operations to skip about half of the tree, so that each lookup, insertion or deletion takes time proportional to the logarithm of the number of items stored in the tree, O(log n) . However, some times the worst case can happen, when the tree isn't balanced and the time complexity is O(n) for all three of these functions.
So, you kind of expect log(N) but it's not absolutely guaranteed.
the searching time complexity of a BST is N, and of binary search in and of itself is logN. What is the difference between the two?
The difference is that a binary search on a sorted array always starts at the middle element (i.e. the median when n is odd). This cannot be guaranteed in a BST. The root might be the middle element, but it doesn't have to be.
For instance, this is a valid BST:
10
/
8
/
5
/
2
/
1
...but it is not a balanced one, and so the process of finding the value 1 given the root of that tree, will include visiting all its nodes. If however the same values were presented in a sorted list (1,2,5,8,10), a binary search would start at 5 and never visit 8 or 10.
Adding self-balancing trees to the table
We can extend the given table with self-balancing search trees, like AVL, and then we get this:
implementation
search
insert
delete
sequential search (unordered list)
𝑁
𝑁
𝑁
binary search (ordered array)
lg𝑁
𝑁
𝑁
BST
𝑁
𝑁
𝑁
AVL
lgN
lgN
lgN
I'm struggling with finding the best of handling tree problems where the input is given as an array/list of pairs.
For example a tree is given as input in the format:
[(1,3),(1,2),(2,5)(2,4),(5,8)]
Where the first value in a pair is the parent, and the second value in a pair is the child.
I'm used to being given the root in tree problems. How would one go about storing this for problems such as "Lowest Common Ancestor"?
It depends on which problem you need to solve. For the problem of finding the lowest common ancestor of two nodes, you'll benefit most from a structure where you can find the parent of a given node in constant time. If it is already given that the nodes are numbered from 1 to n (without gaps), then an array is a good structure, such that arr[child] == parent. If the identifiers for the nodes are not that predictable, then use a hashmap/dictionary, such that map.get(child) == parent.
Is it possible to convert a non balanced BST (the size of the tree is n and the height is h) to RBT in time complexirty of O(n) and space complexity of O(h)?
If you know the number of nodes before hand this is doable, knowing the number of nodes tells you the height of the target RB tree (regardless of what the original tree height).
Therefore you can simply 'peel' nodes off the original tree one-by-one starting from the minimum and place them in the correct tree slot. The easiest way to do this will end up with every row except for a potentially empty bottom row black. (That is, if you have a tree with 7 nodes they will all be black but if you have a tree with 6 the first 2 rows will be black and the bottom row will have 3 red nodes).
This will take O(n) time - to visit each node in the original tree - and O(h) space because you will need to keep track of some bookkeeping depending on where you are in the process.
And note this will only work if you know the number of nodes in the original tree, as it depends on knowing which nodes will be in the bottom row of the produced tree.
The Problem:
Given a BST with N nodes, with a domain of cardinality D (domain being the possible values for the node keys).
Given a key that is in the domain but may or may not be a member of the BST.
At the start, our confidence that the node is in the tree should be 1/D, but as we go deeper into the tree both D and N are split approximately in half. That would suggest that our confidence that our key is a member of the tree should remain constant until we hit the bottom or discover the key. However, I'm not sure if that reasoning is complete, since it seems more like we are choosing N nodes from D.
I was thinking something along the lines of this, but the reasoning here still doesn't seem complete. Can somebody point me in the right direction?
Apriori, the probability that your key in is the tree is N/D.
Without loss of generality, let assume that the node's value range is [1..D].
When you walk down the tree, either:
The current node matches your key, hence P = 1
The current node has value C which is larger than your key, you go left, but you don't know how many items are in the left sub-tree. Now you can make one of these assumptions:
The tree is balanced. The range in the subtree is [1..C-1], and there are (D-1)/2 nodes in the subtree. Hence, P = ((D-1)/2)/(C-1)
The tree is not balanced. The range in the subtree is [1..C-1], and the maximum likelihood estimation for the number of nodes in the subtree is N * (C-1)/D. Hence, P = (N*(C-1)/D)/(C-1) = N/D. (no change)
If you know more about how the tree was constructed - you can make a better MLE for the number of nodes in the subtree.
The current node has value C which is smaller than your key, you go right, but you don't know how many items are in the right sub-tree.
...
I am trying to write a formula to find:
"The number of structurally different binary trees that can exist with nodes that have either 0 or 1 children".
How would I go about doing this?
Seems to me that a "binary tree" that has nodes with only 0 or 1 children is a chain. If by "structurally different" you mean that you treat differently whether a given non-terminal node has a left child or a right child, then observe that you can describe that tree with a binary number that is N-1 bits long. So the number of different trees for a given N would be 2**N-1.
(And, obviously, if you mean how many different "shapes" of the "tree" can exist for a given N, the answer is 1.)