For a given binary tree, find the largest subtree which is also binary search tree?
Example:
Input:
10
/
The previous algorithm (see revisions) was O(n^2)
- we can generalize it to O(n log n)
by noticing the facts that:
b.left.value < b.value
, then b.left
is also in the BST (same for b.right.value ≥ b.value
)So if c is between a and b, and c is not in the BST rooted by b, neither is a (due to (2.)). Using this fact, we can easily determine if a node is in the BST rooted by any given ancestor. We'll do this by passing a node into our function along with a list of its ancestors, and the associated min/maxValues that the current child-node would have to satisfy if indeed that ancestor were the root of the largest BST (we'll call this list ancestorList
). We'll store the entire collection of potential-roots in overallRootsList
Let's define a structure called potentialRoot as follows:
Each potentialRoot contains the following values:
* node: The node we are considering for the root of the BST
* minValue and maxValue: the range another node must fall between to be part of the BST rooted by node (different for every node)
* subNodes: A list of the rest of the nodes in the largest BST rooted by node
The pseudo code looks like this (note that all lists mentioned are lists of potentialRoots):
FindLargestBST(node, ancestorList):
leftList, rightList = empty lists
for each potentialRoot in ancestorList:
if potentialRoot.minValue < node.Value ≤ potentialRoot.maxValue:
add node to potentialRoot.subNodes (due to (1.))
(note that the following copies contain references, not copies, of subNodes)
add copy of potentialRoot to leftList, setting maxValue = node.Value
add copy of potentialRoot to rightList, setting minValue = node.Value
add the potentialRoot (node, -∞, +∞) to leftList, rightList, and overallRootsList
FindLargestBST(node.left, leftList)
FindLargestBST(node.right, rightList)
At the end overallRootsList
will be a list of n
potentialRoots, each with a list of subNodes. The one with the largest subNodes list is your BST.
Since there are < treeHeight values in ancestorList
, then (assuming the tree is balanced), the algorithm runs in O(n log n)