Min Depth of binary tree - binary-tree

I am reading Binary Trees. while practicing coding problems I came across some solutions where it is asked to find Min Depth of Binary Tree.
Now as per my understanding depth is no of edges from root to node (leaf node in case of leaf nodes / binary tree)
What is the min depth of Binary tree {1,2}
As per my solution it should be 1.

My tested solution
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}
int ldepth = minDepth(root.left);
int rdepth = minDepth(root.right);
if(ldepth == 0){
return 1+rdepth;
}else if(rdepth == 0){
return 1+ldepth;
}
return (1 + Math.min(rdepth, ldepth));
}
Here, we calculate ldepth (minimum left subtree depth) and rdepth (minimum right subtree depth) for a node. Then, if ldepth is zero but rdepth is not, that means current node is not a leaf node, so return 1 + rdepth. If both rdepth and ldepth are zeros then still 'if' condition works as we return 1+0 for current leaf node.
Similar logic for 'else if' branch. In 'return' statement as both 'if' conditions has been failed we return 1 (current node) + minimum value of recursive calls to both left and right branch.

Remember a leaf node has neither left nor right child.
1
/
/
2
so here 2 is the leaf node but 1 is not. so minimum depth for this case is 2 assuming depth of root node is 1.
#include<vector>
#include<iostream>
#include<climits>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
int minDepth(TreeNode *root) {
if(root == NULL) return 0;
return getDepth(root);
}
int getDepth(TreeNode *r ){
if(r == NULL) return INT_MAX;
if(r->left == NULL && r->right == NULL)
return 1;
return 1+ min(getDepth(r->left), getDepth(r->right));
}
};

A root node will have a depth of 0, so here depth of the given tree will be 1, refer below recursion and iterative solution to find min dept of binary tree.
Recursive solution :
public static int findMinDepth(BTNode root) {
if (root == null || (root.getLeft() == null && root.getRight() == null)) {
return 0;
}
int ldepth = findMinDepth(root.getLeft());
int rdepth = findMinDepth(root.getRight());
return (Math.min(rdepth + 1, ldepth + 1));
}
Iterative solution :
public static int minDepth(BTNode root) {
int minDepth = Integer.MAX_VALUE;
Stack<BTNode> nodes = new Stack<>();
Stack<BTNode> path = new Stack<>();
if (root == null) {
return -1;
}
nodes.push(root);
while (!nodes.empty()) {
BTNode node = nodes.peek();
if (!path.empty() && node == path.peek()) {
if (node.getLeft() == null && node.getRight() == null && path.size() <= minDepth) {
minDepth = path.size() - 1;
}
path.pop();
nodes.pop();
} else {
path.push(node);
if (node.getRight() != null) {
nodes.push(node.getRight());
}
if (node.getLeft() != null) {
nodes.push(node.getLeft());
}
}
}
return minDepth;
}

The depth o a binary tree is the length of the longest route from the root to the leaf. In my opinion the depth should be 2.

public int minDepth(TreeNode root){
if(root==null)
return 0;
else if(root.left==null && root.right==null)
return 1;
else if(root.left==null)
return 1+minDepth(root.right);
else if(root.right==null)
return 1+minDepth(root.left);
else
return 1+Math.min(minDepth(root.right), minDepth(root.left));
}

As others stated, solution should be 2... But it's semantic, you could simply take result and subtract 1 if your definition of depth is different.
Here's an iterative answer (in C#) (Rajesh Surana answer is a good Recusive answer):
public static int FindMinDepth<T>(BinarySearchTree<T> tree) where T : IComparable<T>
{
var current = tree._root;
int level = 0;
Queue<BSTNode<T>> q = new Queue<BSTNode<T>>();
if (current != null)
q.Enqueue(current);
while (q.Count > 0)
{
level++;
Queue<BSTNode<T>> nq = new Queue<BSTNode<T>>();
foreach (var element in q)
{
if (element.Left == null && element.Right == null)
return level;
if (element.Left != null) nq.Enqueue(element.Left);
if (element.Right != null) nq.Enqueue(element.Right);
}
q = nq;
}
return 0;
//throw new Exception("Min Depth not found!");
}

JavaScript Solution
Given the following Binary Tree structure:
function BT(value, left = null, right = null) {
this.value = value;
this.left = left;
this.right = right;
}
A method to find the minimum depth can be something like so:
BT.prototype.getMinDepth = function() {
if (!this.value) {
return 0;
}
if (!this.left && !this.right) {
return 1;
}
if (this.left && this.right) {
return Math.min(this.left.getMinDepth(), this.right.getMinDepth()) + 1;
}
if (this.left) {
return this.left.getMinDepth() + 1;
}
if (this.right) {
return this.right.getMinDepth() + 1;
}
}
The time complexity of the above solution is O(n) as it traverses all the tree nodes.
A better runtime solution will be to use a breadth traversal method that ends when reaching the first leaf node:
BT.prototype.getMinDepth = function(depth = 0) {
if (!this.value) {
return depth;
}
depth++;
if (!this.left || !this.right) {
return depth;
}
return Math.min(this.left.getMinDepth(depth), this.right.getMinDepth(depth));
}

Given the depth of a path is the number of nodes from the root to the leaf node along this path. The minimum is the path with minimum number of nodes from the root to the LEAF node. In this case, the only leaf node is 2. (A leaf node is defined as a node with no children) Therefore, the only depth and also min depth is 2.
A sample code in Java:
public class Solution {
public int minDepth(TreeNode root) {
if (root==null) return 0;
if ((root.left==null) || (root.right==null)) {
return 1+Math.max(minDepth(root.left),minDepth(root.right));
}
return 1+Math.min(minDepth(root.left),minDepth(root.right));
}
}

Minimum depth is the minimum of the depth of leftsubtree and rightsubtree.
public static int maxDepth(TreeNode root) {
if(root == null) {
return 0;
}
return getDepth(root);
}
private static int getDepth(TreeNode a) {
if(a.left == null & a.right == null) {
return 1;
}
int leftDepth = 0;
int rightDepth = 0;
if(a.left != null) {
leftDepth = getDepth(a.left);
}
if(a.right != null) {
rightDepth = getDepth(a.right);
}
return (Math.min(leftDepth, rightDepth)+1);
}

The minDepth of a binary tree means the shortest distance from the root to a leaf node. Though it is arguable whether the minDepth of your binary tree is 1 or 2, depending on whether you want the shortest distance to a null node, in which case the answer would be 1 OR the shortest distance to a null node whose sibling is ALSO a null node, in which case the answer to Binary tree{1,2} would be 2. Generally, the former is asked, and following the algorithm mentioned in Cracking the Coding Interview , we have the solution as
int minDepth(TreeNode root) {
if (root == null) { return 0;}
return 1 + Math.min(minDepth(root.left), minDepth(root.right));
}

Related

finding second smallest element in binary search tree

int secondSmallestInBST(struct node * tNode) {
if( tNode==NULL || (tNode->left==NULL && tNode->right==NULL) ) // case 1 and 2
exit;
if(tNode->left == NULL){ // case 3
tNode=tNode->right;
while(tNode->left!=NULL){
tNode=tNode->left;
}
return tNode->data;
} // general case.
node * parent=tNode,* child = tNode->left;
while(child->left!=NULL){
parent = child;
child = child->left;
}
return parent->data;
}
not every test cases are passed for my code. suggest me if there is any test case missing in my code. i'm just finding the second smallest element in binary search tree.
int secondSmallestInBST(struct node * tNode) {
if( tNode==NULL || (tNode->left==NULL && tNode->right==NULL) ) // case 1 and 2
exit;
if(tNode->left == NULL){ // case 3
tNode=tNode->right; // find smallest in right bst.
while(tNode->left!=NULL){
tNode=tNode->left;
}
return tNode->data;
} // general case.
if(tNode->left->left==NULL && tNode->left->right!=NULL){ //missed case.
tNode=tNode->left->right;
while(tNode->left!=NULL){
tNode=tNode->left;
}
return tNode->data;
}
node * parent= tNode;
node * child = tNode->left;
while(child->left!=NULL){
parent = child;
child = child->left;
}
return parent->data;
}
//still missing some test cases in this code.
Test for this case - 3 6 2 3.
Tree will look like this :
6
/
2
\
3
The way you are doing, answer will come out to be 6, whereas it is 3.
`
int Successor(Node* root){
while(root->left){
root = root->left;
}
return root->data;
}
int Second_Minimum(Node* root){
// make sure tree is not empty
if(!root)
return -1;
// previous node takes before the last left node
Node* previous = root;
// check left node first for smallest key
if(root->left){
while(root->left){
previous = root;
root = root->left; // 6
} // /
// checks for the case ----> 2
if(!root->right) // \
return previous->data; // 3
}
// Go for minimum successor if exists
if(root->right)
return Successor(root->right);
// checked left and right branch root is on his own
return -1;
}
`
A BST inorder traverse gives elements in order (sorted). So the idea is to return the second element in the traverse(if tree has less than two elements then it won't have second minimum and should return null (not found)).
The following code implements the algorithm. Note that the algorithm can be changed to return the K'th minimum element as well easily.
Code has been written in C# (easily can be written in other languages:-) enjoy!
public static int? FindSecondMimimum(Node node)
{
int current = 0;
return FindKthMinimum(node, 2, ref current);
}
private static int? FindKthMinimum(Node node, int k, ref int current)
{
int? result = null;
if (node == null)
return null;
if (node.Left != null)
{
result = FindKthMinimum(node.Left, k, ref current);
if (result != null)
return result;
}
current++;
if (current == k)
return node.Value;
if (node.Right != null)
{
result = FindKthMinimum(node.Right, k, ref current);
}
return result;
}

Second max in BST

This is an interview question. Find the second max in BST.
The max element is the rightmost leaf in the BST. The second max is either its parent or its left child. So the solution is to traverse the BST to find the rightmost leaf and check its parent and left child.
Does it make sense?
No, that's wrong. Consider this BST:
137
/
42
\
99
Here, the second-to-max value is the rightmost child of the left child of the max value. Your algorithm will need to be updated so that you check the parent of the max value, or the rightmost subchild of the left child of the max.
Also, note that the max is not necessarily the rightmost leaf node, it's the node at the bottom of the right spine of the tree. Above, 137 is not a leaf.
Hope this helps!
Recall that you can list the nodes of a BST in reverse order by doing a modified inorder traversal where you explore the right subtree first. This leads to a simple algorithm:
Node rightmost = findRightmostNode(root)
if (rightmost.left != null) {
return findRightmostNode(rightmost.left)
else{
return rightmost.parent
}
It would return null if the tree has only one element.
public static int findSecondLargestValueInBST(Node root)
{
int secondMax;
Node pre = root;
Node cur = root;
while (cur.Right != null)
{
pre = cur;
cur = cur.Right;
}
if (cur.Left != null)
{
cur = cur.Left;
while (cur.Right != null)
cur = cur.Right;
secondMax = cur.Value;
}
else
{
if (cur == root && pre == root)
//Only one node in BST
secondMax = int.MinValue;
else
secondMax = pre.Value;
}
return secondMax;
}
Much easier iterative approach with Time complexity O(logN) and Space complexity O(1)
public static void main(String[] args) {
BinaryTreeNode result=isBinarySearchTree.secondLargest(rootNode);
System.out.println(result.data);
}
private BinaryTreeNode secondLargest(BinaryTreeNode node) {
BinaryTreeNode prevNode=null; //2nd largest Element
BinaryTreeNode currNode=node;
if(null == currNode)
return prevNode;
while(currNode.right != null){
prevNode=currNode;
currNode=currNode.right;
}
if(currNode.left != null){
currNode=currNode.left;
while(currNode.right != null){
currNode=currNode.right;
}
prevNode=currNode;
}
return prevNode;
}
The algo can be as follows
1. find the largest number in the tree.
private static int findLargestValueInTree(Node root) {
while (root.right != null) {
root = root.right;
}
return root.data;
}
2. Find the largest number in the tree that is smaller than the number we found in step 1
public static int findSecondLargest(Node root, int largest, int current) {
while (root != null) {
if (root.data < largest) {
current = root.data;
root = root.right;
} else {
root = root.left;
}
}
return current;
}
'current' keeps track of the current largest number which is smaller than the number found in step1
Simple javascript implementation.
function Node (value, left, right) {
this.value = value;
this.left = left;
this.right = right;
}
function second (node, prev, wentLeft) {
if (node.right) {
return second(node.right, node, wentLeft);
} else if (node.left) {
return second(node.left, node, true);
} else {
if (wentLeft) return node.value;
return prev.value;
}
}
second(root);
One traversal variant:
public Tree GetSecondMax(Tree root)
{
Tree parentOfMax = null;
var maxNode = GetMaxNode(root, ref parentOfMax);
if (maxNode == root || maxnode.left != null)
{
// if maximum node is root or have left subtree, then return maximum from left subtree
return GetMaxNode(maxnode.left, ref parentOfMax);
}
// if maximum node is not root, then return parent of maximum node
return parentOfMax;
}
private Tree GetMaxNode(Tree root, ref Tree previousNode)
{
if (root == null || root.right == null)
{
// The most right element have reached
return root;
}
// we was there
previousNode = root;
return GetMaxNode(root.right, ref previousNode);
}
int getmax(node *root)
{
if(root->right == NULL)
{
return root->d;
}
return getmax(root->right);
}
int secondmax(node *root)
{
if(root == NULL)
{
return -1;
}
if(root->right == NULL && root->left != NULL)
{
return getmax(root->left);
}
if(root->right != NULL)
{
if(root->right->right == NULL && root->right->left == NULL)
{
return root->d;
}
}
return secondmax(root->right);
}
A very intuitive way to think about this is considering the following two cases.
Let second largest Node as S, and largest node as L.
i) S is inserted to the BST "earlier" than L.
ii) S is inserted to the BST "later" than L.
For the first case, it is obvious that L is the right child of S. It is because any node except for L is smaller than S, therefore will not be put on the right side of S. Therefore when L is being put, it will be the right child of S.
For the second case, by the time when S is inserted, L will the be right most node in the BST. Obviously, L wouldn't have a right child because it is the largest. However, L could have its own left subtree. When S is inserted, S will follow to "right path" until it meets L and then turn left to go to the left subtree of L. Here, we know that all of the nodes in L's left subtree are smaller than S, so S will be the rightmost node in the subtree.
int getSecondLargest(Node root){
if(root==null)
return 0;
Node curr=root;
Node prev=root;
//Go to the largest node
while(curr.right != null){
prev = curr;
curr= curr.right;
}
//If largest Node has left child, Then largest element of tree with its root as largest.left will be the second largest number.
if(curr.left == null)
return prev.data;
else
return findLargest(curr.left);
}
int findLargest(Node root){
// No need toi check for null condition as in getSecondLargest method, its already done.
Node curr=root;
//To find largest just keep on going to right child till leaf is encountered.
while(curr.right != null){
curr = curr.right;
}
return curr.data;
}
I would do it by going though the tree from biggest to smallest element and returning value when asked position is reached. I implemented similar task for second largest value.
void BTree::findSecondLargestValueUtil(Node* r, int &c, int &v)
{
if(r->right) {
this->findSecondLargestValueUtil(r->right, c, v);
}
c++;
if(c==2) {
v = r->value;
return;
}
if(r->left) {
this->findSecondLargestValueUtil(r->left, c, v);
}
}
int BTree::findSecondLargestValue()
{
int c = 0;
int v = -1;
this->findSecondLargestValueUtil(this->root, c, v);
return v;
}
You are close to the right answer.
Here is my attempt at an intuitive answer.
The greatest node is the right most node.
Whatever is under the right most node's left sub-tree is greater than all elements except the right most node. Therefore the greatest node in this sub-tree is the answer.
If there is no left sub-tree then the parent of the right most node is the one that is greater than all the other nodes except the right most node.
The idea is to go all the way to the right until there is nothing on the right. If there's a left, take it and then go all the way to the right. If you took a left, the answer is the last node encountered. Otherwise the answer is the second-last node you encountered.
Here's a recursive solution in Java:
public TreeNode getSecondLargest(TreeNode root) {
if(root == null || (root.left == null && root.right == null))
throw new IllegalArgumentException("The tree must have at least two nodes");
return helper(root, null, false);
}
private TreeNode helper(TreeNode root, TreeNode parent, boolean wentLeft) {
if(root.right != null) return helper(root.right, root, wentLeft);
if(root.left != null && !wentLeft) return helper(root.left, root, true);
if(wentLeft) return root;
else return parent;
}
The time complexity is O(lg n).
This Algorithm to find 2nd Max Element in a BST , will take Time Complexity: O(n) --> in worst case where tree is a right skew tree.
And if the Tree is balanced Tree then the Time Complexity is O(height)
ie O(log n)
And Same Goes with Space Complexity as well: O(n) --> in worst case
O(log n) --> when Tree is balanced.
public TreeNode secondMax(TreeNode root){
return helper(root,null);
}
private TreeNode helper(TreeNode root,TreeNode prev){
if(root==null)
return root;
if(root.right==null && root.left!=null)
return root.left;
else if(root.right==null && root.left==null)
return prev;
return helper(root.right,root);
}
This algorithm does one run on the tree and returns the largest item at Item1 and second largest at Item2.
The sort calls are O(1) because they are independent of the tree size.
So the total time complexity is O(N) and space complexity is O(log(N)) when the tree is balanced.
public static Tuple<int, int> SecondLargest(TreeNode<int> node)
{
int thisValue = node.Value;
if ((node.Left == null || node.Left.Right == null) && node.Right == null)
{
return new Tuple<int, int>(thisValue, -int.MaxValue);
}
else if (node.Left == null || node.Left.Right == null)
{
Tuple<int, int> right = SecondLargest(node.Right);
List<int> sortLargest = new List<int>(new int[] { right.Item1, right.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[2], sortLargest[1]);
}
else if (node.Right == null)
{
Tuple<int, int> left = SecondLargest(node.Left.Right);
List<int> sortLargest = new List<int>(new int[] { left.Item1, left.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[2], sortLargest[1]);
}
else
{
Tuple<int, int> left = SecondLargest(node.Left.Right);
Tuple<int, int> right = SecondLargest(node.Right);
List<int> sortLargest = new List<int>(new int[] { left.Item1, left.Item2, right.Item1, right.Item2, thisValue });
sortLargest.Sort();
return new Tuple<int, int>(sortLargest[4], sortLargest[3]);
}
}

Nodes at a distance k in binary tree

You are given a function printKDistanceNodes which takes in a root node of a binary tree, a start node and an integer K. Complete the function to print the value of all the nodes (one-per-line) which are a K distance from the given start node in sorted order. Distance can be upwards or downwards.
private void printNodeAtN(Node root, Node start, int k) {
if (root != null) {
// calculate if the start is in left or right subtree - if start is
// root this variable is null
Boolean left = isLeft(root, start);
int depth = depth(root, start, 0);
if (depth == -1)
return;
printNodeDown(root, k);
if (root == start)
return;
if (left) {
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.left);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.right);
} else {
System.out.println(root.data);
}
} else {
// similar if the start is in right subtree
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.right);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.left);
} else {
System.out.println(root.data);
}
}
}
}
// print the nodes at depth - "level" from root
void printNode(int level, Node root) {
if (level == 0 && root != null) {
System.out.println(root.data);
} else {
printNode(level - 1, root.left);
printNode(level - 1, root.right);
}
}
// print the children of the start
void printNodeDown(Node start, int k) {
if (start != null) {
if (k == 0) {
System.out.println(start.data);
}
printNodeDown(start.left, k - 1);
printNodeDown(start.right, k - 1);
}
}
private int depth(Node root, Node node, int d) {
if (root == null)
return -1;
if (root != null && node == root) {
return d;
} else {
int left = depth(root.left, node, d + 1);
int right = depth(root.right, node, d + 1);
if (left > right)
return left;
else
return right;
}
}
There is at most one node at distance K which upwards - just start from the start node and move up along parents for K steps. Add this to a sorted data structure.
Then you need to add the downward nodes. To do that you can do a BFS with queue, where you store the depth together with the node when you insert it in the queue (the starting node is at level 0, it's children at level 1 and so on). Then when you pop the nodes if they are at level K add them to the sorted data structure. when you start poping nodes at level K+1 you can stop.
Finally print the nodes from the sorted data structure (they will be sorted).
EDIT: If there is no parent pointer:
Write a recursive function int Go(Node node), which returns the depth of the start node with respect to the passed in node and -1 if the subtree of node doesn't contain start. The function will find the K-th parent as a side effect. Pseudo code:
static Node KthParent = null;
static Node start = ...;
static int K = ...;
int Go(Node node) {
if (node == start) return 0;
intDepth = -1;
if(node.LeftChild != null) {
int leftDepth = Go(node.LeftChild);
if(leftDepth >= 0) intDepth = leftDepth+1;
}
if (intDepth < 0 && node.rightChild != null) {
int rightDepth = Go(node.RightChild);
if(rightDepth >= 0) intDepth = rightDepth+1;
}
if(intDepth == K) KthParent = node;
return intDepth;
}
private static int printNodeAtK(Node root, Node start, int k, boolean found){
if(root != null){
if(k == 0 && found){
System.out.println(root.data);
}
if(root==start || found == true){
int leftd = printNodeAtK(root.left, start, k-1, true);
int rightd = printNodeAtK(root.right,start,k-1,true);
return 1;
}else{
int leftd = printNodeAtK(root.left, start, k, false);
int rightd = printNodeAtK(root.right,start,k,false);
if(leftd == k || rightd == k){
System.out.println(root.data);
}
if(leftd != -1 && leftd > rightd){
return leftd+1;
}else if(rightd != -1 && rightd>leftd){
return rightd+1;
}else{
return -1;
}
}
}
return -1;
}
struct node{
int data;
node* left;
node* right;
bool printed;
};
void print_k_dist(node** root,node** p,int k,int kmax);
void reinit_printed(node **root);
void print_k_dist(node** root,node **p,int k,int kmax)
{
if(*p==NULL) return;
node* par=parent(root,p);
if(k<=kmax &&(*p)->printed==0)
{
cout<<(*p)->data<<" ";
(*p)->printed=1;
k++;
print_k_dist(root,&par,k,kmax);
print_k_dist(root,&(*p)->left,k,kmax);
print_k_dist(root,&(*p)->right,k,kmax);
}
else
return;
}
void reinit_printed(node **root)
{
if(*root==NULL) return;
else
{
(*root)->printed=0;
reinit_printed(&(*root)->left);
reinit_printed(&(*root)->right);
}
}
typedef struct node
{
int data;
struct node *left;
struct node *right;
}node;
void printkdistanceNodeDown(node *n, int k)
{
if(!n)
return ;
if(k==0)
{
printf("%d\n",n->data);
return;
}
printkdistanceNodeDown(n->left,k-1);
printkdistanceNodeDown(n->right,k-1);
}
void printkdistanceNodeDown_fromUp(node* target ,int *k)
{
if(!target)
return ;
if(*k==0)
{
printf("%d\n",target->data);
return;
}
else
{
int val=*k;
printkdistanceNodeDown(target,val-1);
}
}
int printkdistanceNodeUp(node* root, node* n , int k)
{
if(!root)
return 0;
if(root->data==n->data)
return 1;
int pl=printkdistanceNodeUp(root->left,n,k);
int pr=printkdistanceNodeUp(root->right,n,k);
if(pl )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->right,k);
printkdistanceNodeDown_fromUp(root->left,k-1);
}
return 1;
}
if(pr )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->left,k);
printkdistanceNodeDown_fromUp(root->right,k-1);
}
return 1;
}
return 0;
}
void printkdistanceNode(node* root, node* n , int k )
{
if(!root)
return ;
int val=k;
printkdistanceNodeUp(root,n,k);
printkdistanceNodeDown(n,val);
}
caller function: printkdistanceNode(root,n,k);
The output will print all the nodes at a distance k from given node upward and downward.
Here in this code PrintNodesAtKDistance will first try to find the required node.
if(root.value == requiredNode)
When we find the desired node we print all the child nodes at the distance K from this node.
Now our task is to print all nodes which are in other branches(Go up and print). We return -1 till we didn't find our desired node. As we get our desired node we get lPath or rPath >=0 . Now we have to print all nodes which are at distance (lPath/rPath) -1
public void PrintNodes(Node Root, int requiredNode, int iDistance)
{
PrintNodesAtKDistance(Root, requiredNode, iDistance);
}
public int PrintNodesAtKDistance(Node root, int requiredNode, int iDistance)
{
if ((root == null) || (iDistance < 0))
return -1;
int lPath = -1, rPath = -1;
if(root.value == requiredNode)
{
PrintChildNodes(root, iDistance);
return iDistance - 1;
}
lPath = PrintNodesAtKDistance(root.left, requiredNode, iDistance);
rPath = PrintNodesAtKDistance(root.right, requiredNode, iDistance);
if (lPath > 0)
{
PrintChildNodes(root.right, lPath - 1);
return lPath - 1;
}
else if(lPath == 0)
{
Debug.WriteLine(root.value);
}
if(rPath > 0)
{
PrintChildNodes(root.left, rPath - 1);
return rPath - 1;
}
else if (rPath == 0)
{
Debug.WriteLine(root.value);
}
return -1;
}
public void PrintChildNodes(Node aNode, int iDistance)
{
if (aNode == null)
return;
if(iDistance == 0)
{
Debug.WriteLine(aNode.value);
}
PrintChildNodes(aNode.left, iDistance - 1);
PrintChildNodes(aNode.right, iDistance - 1);
}
Here is complete java program . Inspired from geeksforgeeks Algorith
// Java program to print all nodes at a distance k from given node
class BinaryTreePrintKDistance {
Node root;
/*
* Recursive function to print all the nodes at distance k in tree (or
* subtree) rooted with given root.
*/
void printKDistanceForDescendant(Node targetNode, int currentDist,
int inputDist) {
// Base Case
if (targetNode == null || currentDist > inputDist)
return;
// If we reach a k distant node, print it
if (currentDist == inputDist) {
System.out.print(targetNode.data);
System.out.println("");
return;
}
++currentDist;
// Recur for left and right subtrees
printKDistanceForDescendant(targetNode.left, currentDist, inputDist);
printKDistanceForDescendant(targetNode.right, currentDist, inputDist);
}
public int printkdistance(Node targetNode, Node currentNode,
int inputDist) {
if (currentNode == null) {
return -1;
}
if (targetNode.data == currentNode.data) {
printKDistanceForDescendant(currentNode, 0, inputDist);
return 0;
}
int ld = printkdistance(targetNode, currentNode.left, inputDist);
if (ld != -1) {
if (ld + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.right, 0, inputDist
- ld - 2);
}
return ld + 1;
}
int rd = printkdistance(targetNode, currentNode.right, inputDist);
if (rd != -1) {
if (rd + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.left, 0, inputDist - rd
- 2);
}
return rd + 1;
}
return -1;
}
// Driver program to test the above functions
#SuppressWarnings("unchecked")
public static void main(String args[]) {
BinaryTreePrintKDistance tree = new BinaryTreePrintKDistance();
/* Let us construct the tree shown in above diagram */
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
Node target = tree.root.left;
tree.printkdistance(target, tree.root, 2);
}
static class Node<T> {
public Node left;
public Node right;
public T data;
Node(T data) {
this.data = data;
}
}
}

Finding height in Binary Search Tree

I was wondering if anybody could help me rework this method to find the height of a binary search tree. So far, my code looks like this. However, the answer I'm getting is larger than the actual height by 1. But when I remove the +1 from my return statements, it's less than the actual height by 1. I'm still trying to wrap my head around recursion with these BST. Any help would be much appreciated.
public int findHeight(){
if(this.isEmpty()){
return 0;
}
else{
TreeNode<T> node = root;
return findHeight(node);
}
}
private int findHeight(TreeNode<T> aNode){
int heightLeft = 0;
int heightRight = 0;
if(aNode.left!=null)
heightLeft = findHeight(aNode.left);
if(aNode.right!=null)
heightRight = findHeight(aNode.right);
if(heightLeft > heightRight){
return heightLeft+1;
}
else{
return heightRight+1;
}
}
The problem lies in your base case.
"The height of a tree is the length of the path from the root to the deepest node in the tree. A (rooted) tree with only a node (the root) has a height of zero." - Wikipedia
If there is no node, you want to return -1 not 0. This is because you are adding 1 at the end.
So if there isn't a node, you return -1 which cancels out the +1.
int findHeight(TreeNode<T> aNode) {
if (aNode == null) {
return -1;
}
int lefth = findHeight(aNode.left);
int righth = findHeight(aNode.right);
if (lefth > righth) {
return lefth + 1;
} else {
return righth + 1;
}
}
The height of a binary search tree is equal to number of layers - 1.
See the diagram at http://en.wikipedia.org/wiki/Binary_tree
Your recursion is good, so just subtract one at the root level.
Also note, you can clean up the function a bit by handling null nodes:
int findHeight(node) {
if (node == null) return 0;
return 1 + max(findHeight(node.left), findHeight(node.right));
}
int getHeight(Node node) {
if (node == null) return -1;
return 1 + Math.max(getHeight(node.left), getHeight(node.right));
}
In my opinion, your code would benefit from being simplified a bit. Rather than attempting to end the recursion when a child pointer is null, only end it when the current pointer is null. That makes the code a lot simpler to write. In pseudo-code, it looks something like this:
if (node = null)
return 0;
else
left = height(node->left);
right = height(node->right);
return 1 + max(left, right);
class Solution{
public static int getHeight(Node root) {
int height = -1;
if (root == null) {
return height;
} else {
height = 1 + Math.max(getHeight(root.left), getHeight(root.right));
}
return height;
}
For people like me who like one line solutions:
public int getHeight(Node root) {
return Math.max(root.left != null ? getHeight(root.left) : -1,
root.right != null ? getHeight(root.right) : -1)
+ 1;
}
Here's a concise and hopefully correct way to express it:
private int findHeight(TreeNode<T> aNode){
if(aNode == null || (aNode.left == null && aNode.right == null))
return 0;
return Math.max(findHeight(aNode.left), findHeight(aNode.right)) + 1;
}
If the current node is null, there's no tree. If both children are, there's a single layer, which means 0 height. This uses the definition of height (mentioned by Stephen) as # of layers - 1
This is untested, but fairly obviously correct:
private int findHeight(Treenode<T> aNode) {
if (aNode.left == null && aNode.right == null) {
return 0; // was 1; apparently a node with no children has a height of 0.
} else if (aNode.left == null) {
return 1 + findHeight(aNode.right);
} else if (aNode.right == null) {
return 1 + findHeight(aNode.left);
} else {
return 1 + max(findHeight(aNode.left), findHeight(aNode.right));
}
}
Often simplifying your code is easier than figuring out why it's off by one. This code is easy to understand: the four possible cases are clearly handled in an obviously correct manner:
If both the left and right trees are null, return 0, since a single node by definition has a height of 0. (was 1)
If either the left or right trees (but not both!) are null, return the height of the non-null tree, plus 1 to account for the added height of the current node.
If neither tree is null, return the height of the taller subtree, again plus one for the current node.
public void HeightRecursive()
{
Console.WriteLine( HeightHelper(root) );
}
private int HeightHelper(TreeNode node)
{
if (node == null)
{
return -1;
}
else
{
return 1 + Math.Max(HeightHelper(node.LeftNode),HeightHelper(node.RightNode));
}
}
C# code.
Include these two methods in your BST class. you need two method to calculate height of tree. HeightHelper calculate it, & HeightRecursive print it in main().
The definition given above of the height is incorrect. That is the definition of the depth.
"The depth of a node M in a tree is the length of the path from the root of the tree to M. The height of a tree is one more than the depth of the deepest node in the tree. All nodes of depth d are at level d in the tree. The root is the only node at level 0, and its depth is 0."
Citation: "A Practical Introduction to Data Structures and Algorithm Analysis"
Edition 3.2 (Java Version)
Clifford A. Shaffer
Department of Computer Science
Virginia Tech
Blacksburg, VA 24061
public int height(){
if(this.root== null) return 0;
int leftDepth = nodeDepth(this.root.left, 1);
int rightDepth = nodeDepth(this.root.right, 1);
int height = leftDepth > rightDepth? leftDepth: rightDepth;
return height;
}
private int nodeDepth(Node node, int startValue){
int nodeDepth = 0;
if(node.left == null && node.right == null) return startValue;
else{
startValue++;
if(node.left!= null){
nodeDepth = nodeDepth(node.left, startValue);
}
if(node.right!= null){
nodeDepth = nodeDepth(node.right, startValue);
}
}
return nodeDepth;
}
//function to find height of BST
int height(Node* root) {
if(root == NULL){
return -1;
}
int sum=0;
int rheight = height(root->right);
int lheight = height(root->left);
if(lheight>rheight){
sum = lheight +1;
}
if(rheight > lheight){
sum = rheight + 1;
}
return sum;
}
int height(Node* root) {
if(root==NULL) return -1;
return max(height(root->left),height(root->right))+1;
}
Take of maximum height from left and right subtree and add 1 to it.This also handles the base case(height of Tree with 1 node is 0).
I know that I’m late to the party. After looking into wonderful answers provided here, I thought mine will add some value to this post. Although the posted answers are amazing and easy to understand however, all are calculating the height to the BST in linear time. I think this can be improved and Height can be retrieved in constant time, hence writing this answer – hope you will like it.
Let’s start with the Node class:
public class Node
{
public Node(string key)
{
Key = key;
Height = 1;
}
public int Height { get; set; }
public string Key { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
public override string ToString()
{
return $"{Key}";
}
}
BinarySearchTree class
So you might have guessed the trick here… Im keeping node instance variable Height to keep track of each node when added.
Lets move to the BinarySearchTree class that allows us to add nodes into our BST:
public class BinarySearchTree
{
public Node RootNode { get; private set; }
public void Put(string key)
{
if (ContainsKey(key))
{
return;
}
RootNode = Put(RootNode, key);
}
private Node Put(Node node, string key)
{
if (node == null) return new Node(key);
if (node.Key.CompareTo(key) < 0)
{
node.Right = Put(node.Right, key);
}
else
{
node.Left = Put(node.Left, key);
}
// since each node has height property that is maintained through this Put method that creates the binary search tree.
// calculate the height of this node by getting the max height of its left or right subtree and adding 1 to it.
node.Height = Math.Max(GetHeight(node.Left), GetHeight(node.Right)) + 1;
return node;
}
private int GetHeight(Node node)
{
return node?.Height ?? 0;
}
public Node Get(Node node, string key)
{
if (node == null) return null;
if (node.Key == key) return node;
if (node.Key.CompareTo(key) < 0)
{
// node.Key = M, key = P which results in -1
return Get(node.Right, key);
}
return Get(node.Left, key);
}
public bool ContainsKey(string key)
{
Node node = Get(RootNode, key);
return node != null;
}
}
Once we have added the key, values in the BST, we can just call Height property on the RootNode object that will return us the Height of the RootNode tree in constant time.
The trick is to keep the height updated when a new node is added into the tree.
Hope this helps someone out there in the wild world of computer science enthusiast!
Unit test:
[TestCase("SEARCHEXAMPLE", 6)]
[TestCase("SEBAQRCHGEXAMPLE", 6)]
[TestCase("STUVWXYZEBAQRCHGEXAMPLE", 8)]
public void HeightTest(string data, int expectedHeight)
{
// Arrange.
var runner = GetRootNode(data);
// Assert.
Assert.AreEqual(expectedHeight, runner.RootNode.Height);
}
private BinarySearchTree GetRootNode(string data)
{
var runner = new BinarySearchTree();
foreach (char nextKey in data)
{
runner.Put(nextKey.ToString());
}
return runner;
}
Note: This idea of keeping the Height of tree maintained in every Put operation is inspired by the Size of BST method found in the 3rd chapter (page 399) of Algorithm (Fourth Edition) book.
I guess this question could mean two different things...
Height is the number of nodes in the longest branch:-
int calcHeight(node* root){
if(root==NULL)
return 0;
int l=calcHeight(root->left);
int r=calcHeight(root->right);
if(l>r)
return l+1;
else
return r+1;
}
Height is the total number of nodes in the tree itself:
int calcSize(node* root){
if(root==NULL)
return 0;
return(calcSize(root->left)+1+calcSize(root->right));
}
public int getHeight(Node node)
{
if(node == null)
return 0;
int left_val = getHeight(node.left);
int right_val = getHeight(node.right);
if(left_val > right_val)
return left_val+1;
else
return right_val+1;
}
Set a tempHeight as a static variable(initially 0).
static void findHeight(Node node, int count) {
if (node == null) {
return;
}
if ((node.right == null) && (node.left == null)) {
if (tempHeight < count) {
tempHeight = count;
}
}
findHeight(node.left, ++count);
count--; //reduce the height while traversing to a different branch
findHeight(node.right, ++count);
}
Here is a solution in Java a bit lengthy but works..
public static int getHeight (Node root){
int lheight = 0, rheight = 0;
if(root==null) {
return 0;
}
else {
if(root.left != null) {
lheight = 1 + getHeight(root.left);
System.out.println("lheight" + " " + lheight);
}
if (root.right != null) {
rheight = 1+ getHeight(root.right);
System.out.println("rheight" + " " + rheight);
}
if(root != null && root.left == null && root.right == null) {
lheight += 1;
rheight += 1;
}
}
return Math.max(lheight, rheight);
}
int getHeight(Node* root)
{
if(root == NULL) return -1;
else return max(getHeight(root->left), getHeight(root->right)) + 1;
}
Here is a solution in C#
private static int heightOfTree(Node root)
{
if (root == null)
{
return 0;
}
int left = 1 + heightOfTree(root.left);
int right = 1 + heightOfTree(root.right);
return Math.Max(left, right);
}
For anyone else that reads this!!!!
HEIGHT is defined as the number of nodes in the longest path from the root node to a leaf node. Therefore: a tree with only a root node has a height of 1 and not 0.
The LEVEL of a given node is the distance from the root plus 1. Therefore: The root is on level 1, its child nodes are on level 2 and so on.
(Information courtesy of Data Structures: Abstraction and Design Using Java, 2nd Edition, by Elliot B. Koffman & Paul A. T. Wolfgang) - Book used in Data Structures Course I am currently taking at Columbus State University.
enter image description here
According to "Introduction to Algorithms" by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, following is the definition of tree height:
The height of a node in a
tree is the number of edges on the longest simple downward path from the node to
a leaf, and the height of a tree is the height of its root. The height of a tree is also
equal to the largest depth of any node in the tree.
Following is my ruby solution. Most of the people forgot about height of empty tree or tree of single node in their implementation.
def height(node, current_height)
return current_height if node.nil? || (node.left.nil? && node.right.nil?)
return [height(node.left, current_height + 1), height(node.right, current_height + 1)].max if node.left && node.right
return height(node.left, current_height + 1) if node.left
return height(node.right, current_height + 1)
end
int maxDepth(BinaryTreeNode root) {
if(root == null || (root.left == null && root.right == null)) {
return 0;
}
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
}
Height of Binary Tree
public static int height(Node root)
{
// Base case: empty tree has height 0
if (root == null) {
return 0;
}
// recursively for left and right subtree and consider maximum depth
return 1 + Math.max(height(root.left), height(root.right));
}
I struggled with this myself trying to find something elegant that still resulted in the correct value. Here's what I came up with using Swift. Note that height is a computed variable and technically not a function.
class Node<T: Comparable>: NSObject
{
var left: Node<T>? = nil
var right: Node<T>? = nil
var isLeaf: Bool { left == nil && right == nil }
var height: Int {
if isLeaf { return 0 }
return 1 + max(left?.height ?? 0, right?.height ?? 0)
}
}
There's more to this Node definition but you can see the left and right variables (possibly nil) and an isLeaf var that is true when both left and right are nil. Might not be the most efficient but I believe it yields the correct result.
The BST definition also has a computed height variable and returns -1 when the tree is empty.
class BST<T: Comparable>: NSObject
{
var root: Node<T>?
var height: Int { root != nil ? root!.height : -1 }
}
HackerRank Day 22: Finding height in Binary Search Tree, in C#.
static int getHeight(Node root)
{
//Write your code here
int countr = 0,countl=0;
Node Leftsubtree=root.left;
Node rightsubtree = root.right;
int data=root.data;
if(root==null ||(root.left == null && root.right == null))
{
return 0;
}
else
{
while (Leftsubtree != null)
{
if(Leftsubtree.data<data)
{
Leftsubtree = Leftsubtree.left==null?Leftsubtree.right:Leftsubtree.left;
countl++;
}
}
while (rightsubtree != null)
{
if (rightsubtree.data > data)
{
rightsubtree = rightsubtree.right == null ? rightsubtree.left : rightsubtree.right;
countr++;
}
}
}
return countr >= countl ? countr : countl;
}

How do you validate a binary search tree?

I read on here of an exercise in interviews known as validating a binary search tree.
How exactly does this work? What would one be looking for in validating a binary search tree? I have written a basic search tree, but never heard of this concept.
Actually that is the mistake everybody does in an interview.
Leftchild must be checked against (minLimitof node,node.value)
Rightchild must be checked against (node.value,MaxLimit of node)
IsValidBST(root,-infinity,infinity);
bool IsValidBST(BinaryNode node, int MIN, int MAX)
{
if(node == null)
return true;
if(node.element > MIN
&& node.element < MAX
&& IsValidBST(node.left,MIN,node.element)
&& IsValidBST(node.right,node.element,MAX))
return true;
else
return false;
}
Another solution (if space is not a constraint):
Do an inorder traversal of the tree and store the node values in an array. If the array is in sorted order, its a valid BST otherwise not.
"Validating" a binary search tree means that you check that it does indeed have all smaller items on the left and large items on the right. Essentially, it's a check to see if a binary tree is a binary search tree.
The best solution I found is O(n) and it uses no extra space. It is similar to inorder traversal but instead of storing it to array and then checking whether it is sorted we can take a static variable and check while inorder traversing whether array is sorted.
static struct node *prev = NULL;
bool isBST(struct node* root)
{
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;
// Allows only distinct valued nodes
if (prev != NULL && root->data <= prev->data)
return false;
prev = root;
return isBST(root->right);
}
return true;
}
Iterative solution using inorder traversal.
bool is_bst(Node *root) {
if (!root)
return true;
std::stack<Node*> stack;
bool started = false;
Node *node = root;
int prev_val;
while(true) {
if (node) {
stack.push(node);
node = node->left();
continue;
}
if (stack.empty())
break;
node = stack.top();
stack.pop();
/* beginning of bst check */
if(!started) {
prev_val = node->val();
started = true;
} else {
if (prev_val > node->val())
return false;
prev_val = node->val();
}
/* end of bst check */
node = node->right();
}
return true;
}
Here is my solution in Clojure:
(defstruct BST :val :left :right)
(defn in-order [bst]
(when-let [{:keys [val, left, right]} bst]
(lazy-seq
(concat (in-order left) (list val) (in-order right)))))
(defn is-strictly-sorted? [col]
(every?
(fn [[a b]] (< a b))
(partition 2 1 col)))
(defn is-valid-BST [bst]
(is-strictly-sorted? (in-order bst)))
Since the in-order traversal of a BST is a non-decrease sequence, we could use this property to judge whether a binary tree is BST or not. Using Morris traversal and maintaining the pre node, we could get a solution in O(n) time and O(1) space complexity. Here is my code
public boolean isValidBST(TreeNode root) {
TreeNode pre = null, cur = root, tmp;
while(cur != null) {
if(cur.left == null) {
if(pre != null && pre.val >= cur.val)
return false;
pre = cur;
cur = cur.right;
}
else {
tmp = cur.left;
while(tmp.right != null && tmp.right != cur)
tmp = tmp.right;
if(tmp.right == null) { // left child has not been visited
tmp.right = cur;
cur = cur.left;
}
else { // left child has been visited already
tmp.right = null;
if(pre != null && pre.val >= cur.val)
return false;
pre = cur;
cur = cur.right;
}
}
}
return true;
}
bool BinarySearchTree::validate() {
int minVal = -1;
int maxVal = -1;
return ValidateImpl(root, minVal, maxVal);
}
bool BinarySearchTree::ValidateImpl(Node *currRoot, int &minVal, int &maxVal)
{
int leftMin = -1;
int leftMax = -1;
int rightMin = -1;
int rightMax = -1;
if (currRoot == NULL) return true;
if (currRoot->left) {
if (currRoot->left->value < currRoot->value) {
if (!ValidateImpl(currRoot->left, leftMin, leftMax)) return false;
if (leftMax != currRoot->left->value && currRoot->value < leftMax) return false;
}
else
return false;
} else {
leftMin = leftMax = currRoot->value;
}
if (currRoot->right) {
if (currRoot->right->value > currRoot->value) {
if(!ValidateImpl(currRoot->right, rightMin, rightMax)) return false;
if (rightMin != currRoot->right->value && currRoot->value > rightMin) return false;
}
else return false;
} else {
rightMin = rightMax = currRoot->value;
}
minVal = leftMin < rightMin ? leftMin : rightMin;
maxVal = leftMax > rightMax ? leftMax : rightMax;
return true;
}
"It's better to define an invariant first. Here the invariant is -- any two sequential elements of the BST in the in-order traversal must be in strictly increasing order of their appearance (can't be equal, always increasing in in-order traversal). So solution can be just a simple in-order traversal with remembering the last visited node and comparison the current node against the last visited one to '<' (or '>')."
I got this question in a phone interview recently and struggled with it more than I should have. I was trying to keep track of minimums and maximums in child nodes and I just couldn't wrap my brain around the different cases under the pressure of an interview.
After thinking about it while falling asleep last night, I realized that it is as simple as keeping track of the last node you've visited during an inorder traversal. In Java:
public <T extends Comparable<T>> boolean isBst(TreeNode<T> root) {
return isBst(root, null);
}
private <T extends Comparable<T>> boolean isBst(TreeNode<T> node, TreeNode<T> prev) {
if (node == null)
return true;
if (isBst(node.left, prev) && (prev == null || prev.compareTo(node) < 0 ))
return isBst(node.right, node);
return false;
}
In Java and allowing nodes with same value in either sub-tree:
public boolean isValid(Node node) {
return isValid(node, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
private boolean isValid(Node node, int minLimit, int maxLimit) {
if (node == null)
return true;
return minLimit <= node.value && node.value <= maxLimit
&& isValid(node.left, minLimit, node.value)
&& isValid(node.right, node.value, maxLimit);
}
Here is my answer in python, it has all the corner cases addressed and well tested in hackerrank website
""" Node is defined as
class node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
"""
def checkBST(root):
return checkLeftSubTree(root, root.left) and checkRightSubTree(root, root.right)
def checkLeftSubTree(root, subTree):
if not subTree:
return True
else:
return root.data > subTree.data \
and checkLeftSubTree(root, subTree.left) \
and checkLeftSubTree(root, subTree.right) \
and checkLeftSubTree(subTree, subTree.left) \
and checkRightSubTree(subTree, subTree.right)
def checkRightSubTree(root, subTree):
if not subTree:
return True
else:
return root.data < subTree.data \
and checkRightSubTree(root, subTree.left) \
and checkRightSubTree(root, subTree.right) \
and checkRightSubTree(subTree, subTree.right) \
and checkLeftSubTree(subTree, subTree.left)
// using inorder traverse based Impl
bool BinarySearchTree::validate() {
int val = -1;
return ValidateImpl(root, val);
}
// inorder traverse based Impl
bool BinarySearchTree::ValidateImpl(Node *currRoot, int &val) {
if (currRoot == NULL) return true;
if (currRoot->left) {
if (currRoot->left->value > currRoot->value) return false;
if(!ValidateImpl(currRoot->left, val)) return false;
}
if (val > currRoot->value) return false;
val = currRoot->value;
if (currRoot->right) {
if (currRoot->right->value < currRoot->value) return false;
if(!ValidateImpl(currRoot->right, val)) return false;
}
return true;
}
bool ValidateBST(Node *pCurrentNode, int nMin = INT_MIN, int nMax = INT_MAX)
{
return
(
pCurrentNode == NULL
)
||
(
(
!pCurrentNode->pLeftNode ||
(
pCurrentNode->pLeftNode->value < pCurrentNode->value &&
pCurrentNode->pLeftNode->value < nMax &&
ValidateBST(pCurrentNode->pLeftNode, nMin, pCurrentNode->value)
)
)
&&
(
!pCurrentNode->pRightNode ||
(
pCurrentNode->pRightNode->value > pCurrentNode->value &&
pCurrentNode->pRightNode->value > nMin &&
ValidateBST(pCurrentNode->pRightNode, pCurrentNode->value, nMax)
)
)
);
}
To find out whether given BT is BST for any datatype, you need go with below approach.
1. call recursive function till the end of leaf node using inorder traversal
2. Build your min and max values yourself.
Tree element must have less than / greater than operator defined.
#define MIN (FirstVal, SecondVal) ((FirstVal) < (SecondVal)) ? (FirstVal):(SecondVal)
#define MAX (FirstVal, SecondVal) ((FirstVal) > (SecondVal)) ? (FirstVal):(SecondVal)
template <class T>
bool IsValidBST (treeNode &root)
{
T min, max;
return IsValidBST (root, &min, &max);
}
template <class T>
bool IsValidBST (treeNode *root, T *MIN , T *MAX)
{
T leftMin, leftMax, rightMin, rightMax;
bool isValidBST;
if (root->leftNode == NULL && root->rightNode == NULL)
{
*MIN = root->element;
*MAX = root->element;
return true;
}
isValidBST = IsValidBST (root->leftNode, &leftMin, &leftMax);
if (isValidBST)
isValidBST = IsValidBST (root->rightNode, &rightMin, &rightMax);
if (isValidBST)
{
*MIN = MIN (leftMIN, rightMIN);
*Max = MAX (rightMax, leftMax);
}
return isValidBST;
}
bool isBST(struct node* root)
{
static struct node *prev = NULL;
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;
// Allows only distinct valued nodes
if (prev != NULL && root->data <= prev->data)
return false;
prev = root;
return isBST(root->right);
}
return true;
}
Works Fine :)
Recursion is easy but iterative approach is better, there is one iterative version above but it's way too complex than necessary. Here is the best solution in c++ you'll ever find anywhere:
This algorithm runs in O(N) time and needs O(lgN) space.
struct TreeNode
{
int value;
TreeNode* left;
TreeNode* right;
};
bool isBST(TreeNode* root) {
vector<TreeNode*> stack;
TreeNode* prev = nullptr;
while (root || stack.size()) {
if (root) {
stack.push_back(root);
root = root->left;
} else {
if (prev && stack.back()->value <= prev->value)
return false;
prev = stack.back();
root = prev->right;
stack.pop_back();
}
}
return true;
}
I wrote a solution to use inorder Traversal BST and check whether the nodes is
increasing order for space O(1) AND time O(n). TreeNode predecessor is prev node. I am not sure the solution is right or not. Because the inorder Traversal can not define a whole tree.
public boolean isValidBST(TreeNode root, TreeNode predecessor) {
boolean left = true, right = true;
if (root.left != null) {
left = isValidBST(root.left, predecessor);
}
if (!left)
return false;
if (predecessor.val > root.val)
return false;
predecessor.val = root.val;
if (root.right != null) {
right = isValidBST(root.right, predecessor);
}
if (!right)
return false;
return true;
}
Following is the Java implementation of BST validation, where we travel the tree in-order DFS and it returns false if we get any number which is greater than last number.
static class BSTValidator {
private boolean lastNumberInitialized = false;
private int lastNumber = -1;
boolean isValidBST(TreeNode node) {
if (node.left != null && !isValidBST(node.left)) return false;
// In-order visiting should never see number less than previous
// in valid BST.
if (lastNumberInitialized && (lastNumber > node.getData())) return false;
if (!lastNumberInitialized) lastNumberInitialized = true;
lastNumber = node.getData();
if (node.right != null && !isValidBST(node.right)) return false;
return true;
}
}
Recursive solution:
isBinary(root)
{
if root == null
return true
else if( root.left == NULL and root.right == NULL)
return true
else if(root.left == NULL)
if(root.right.element > root.element)
rerturn isBInary(root.right)
else if (root.left.element < root.element)
return isBinary(root.left)
else
return isBInary(root.left) and isBinary(root.right)
}
Iterative solution.
private static boolean checkBst(bst node) {
Stack<bst> s = new Stack<bst>();
bst temp;
while(node!=null){
s.push(node);
node=node.left;
}
while (!s.isEmpty()){
node = s.pop();
System.out.println(node.val);
temp = node;
if(node.right!=null){
node = node.right;
while(node!=null)
{
//Checking if the current value is lesser than the previous value and ancestor.
if(node.val < temp.val)
return false;
if(!s.isEmpty())
if(node.val>s.peek().val)
return false;
s.push(node);
if(node!=null)
node=node.left;
}
}
}
return true;
}
This works for duplicates.
// time O(n), space O(logn)
// pseudocode
is-bst(node, min = int.min, max = int.max):
if node == null:
return true
if node.value <= min || max < node.value:
return false
return is-bst(node.left, min, node.value)
&& is-bst(node.right, node.value, max)
This works even for int.min and int.max values using Nullable types.
// time O(n), space O(logn)
// pseudocode
is-bst(node, min = null, max = null):
if node == null:
return true
if min != null && node.value <= min
return false
if max != null && max < node.value:
return false
return is-bst(node.left, min, node.value)
&& is-bst(node.right, node.value, max)
Inspired by http://www.jiuzhang.com/solutions/validate-binary-search-tree/
There are two general solutions: traversal and divide && conquer.
public class validateBinarySearchTree {
public boolean isValidBST(TreeNode root) {
return isBSTTraversal(root) && isBSTDivideAndConquer(root);
}
// Solution 1: Traversal
// The inorder sequence of a BST is a sorted ascending list
private int lastValue = 0; // the init value of it doesn't matter.
private boolean firstNode = true;
public boolean isBSTTraversal(TreeNode root) {
if (root == null) {
return true;
}
if (!isValidBST(root.left)) {
return false;
}
// firstNode is needed because of if firstNode is Integer.MIN_VALUE,
// even if we set lastValue to Integer.MIN_VALUE, it will still return false
if (!firstNode && lastValue >= root.val) {
return false;
}
firstNode = false;
lastValue = root.val;
if (!isValidBST(root.right)) {
return false;
}
return true;
}
// Solution 2: divide && conquer
private class Result {
int min;
int max;
boolean isBST;
Result(int min, int max, boolean isBST) {
this.min = min;
this.max = max;
this.isBST = isBST;
}
}
public boolean isBSTDivideAndConquer(TreeNode root) {
return isBSTHelper(root).isBST;
}
public Result isBSTHelper(TreeNode root) {
// For leaf node's left or right
if (root == null) {
// we set min to Integer.MAX_VALUE and max to Integer.MIN_VALUE
// because of in the previous level which is the leaf level,
// we want to set the min or max to that leaf node's val (in the last return line)
return new Result(Integer.MAX_VALUE, Integer.MIN_VALUE, true);
}
Result left = isBSTHelper(root.left);
Result right = isBSTHelper(root.right);
if (!left.isBST || !right.isBST) {
return new Result(0,0, false);
}
// For non-leaf node
if (root.left != null && left.max >= root.val
&& root.right != null && right.min <= root.val) {
return new Result(0, 0, false);
}
return new Result(Math.min(left.min, root.val),
Math.max(right.max, root.val), true);
}
}
One liner
bool is_bst(Node *root, int from, int to) {
return (root == NULL) ? true :
root->val >= from && root->val <= to &&
is_bst(root->left, from, root->val) &&
is_bst(root->right, root->val, to);
}
Pretty long line though.
Here's a solution in java from sedgewick's algorithm class.
Check the full BST implementation here
I added some explanatory comments
private boolean isBST() {
return isBST(root, null, null);
}
private boolean isBST(Node x, Key min, Key max) {
if (x == null) return true;
// when checking right subtree min is key of x's parent
if (min != null && x.key.compareTo(min) <= 0) return false;
// when checking left subtree, max is key of x's parent
if (max != null && x.key.compareTo(max) >= 0) return false;
// check left subtree and right subtree
return isBST(x.left, min, x.key) && isBST(x.right, x.key, max);
}
The iterative function checks iteratively whether given tree is a binary search tree.
The recurse function checks recursively whether given tree is a binary search tree or not.
In iterative function I use bfs for checking BST.
In recurse function I use dfs for checking BST.
Both solutions have a time complexity of O(n)
iterative solution has an advantage over recurse solution and that is iterative solution does early stopping.
Even recurse function can be optimized for early stopping by global flag value.
The idea of both the solution is that the left child should be within the range of -infinity to the value of its parent node whihch is the root node
The right child should be within the range of +infinity to the value of its parent node whihch is the root node
And go on comparing the current node's value within the range. If any node's value is not in the range then return False
class Solution:
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
return self.iterative(root)
# return self.recurse(root, float("inf"), float("-inf"))
def iterative(self, root):
if not root:
return True
level = [[root, -float("inf"), float("inf")]]
while level:
next_level = []
for element in level:
node, min_val, max_val = element
if min_val<node.val<max_val:
if node.left:
next_level.append([node.left, min_val, node.val])
if node.right:
next_level.append([node.right, node.val, max_val])
else:
return False
level = next_level
return True
def recurse(self, root, maxi, mini):
if root is None:
return True
if root.val < mini or root.val > maxi:
return False
return self.recurse(root.left, root.val-1, mini) and self.recurse(root.right, maxi, root.val+1)
Python implementation example. This example uses type annotations. However since Node class uses itself we need to include as a first line of the module:
from __future__ import annotations
Otherwise, you will get name 'Node' is not defined error. This example also uses dataclass as an example. To check if it's BST it uses recursion for checking left and right nodes values.
"""Checks if Binary Search Tree (BST) is balanced"""
from __future__ import annotations
import sys
from dataclasses import dataclass
MAX_KEY = sys.maxsize
MIN_KEY = -sys.maxsize - 1
#dataclass
class Node:
value: int
left: Node
right: Node
#property
def is_leaf(self) -> bool:
"""Check if node is a leaf"""
return not self.left and not self.right
def is_bst(node: Node, min_value: int, max_value: int) -> bool:
if node.value < min_value or max_value < node.value:
return False
elif node.is_leaf:
return True
return is_bst(node.left, min_value, node.value) and is_bst(
node.right, node.value, max_value
)
if __name__ == "__main__":
node5 = Node(5, None, None)
node25 = Node(25, None, None)
node40 = Node(40, None, None)
node10 = Node(10, None, None)
# balanced tree
node30 = Node(30, node25, node40)
root = Node(20, node10, node30)
print(is_bst(root, MIN_KEY, MAX_KEY))
# unbalanced tree
node30 = Node(30, node5, node40)
root = Node(20, node10, node30)
print(is_bst(root, MIN_KEY, MAX_KEY))
BST example
public bool IsBinarySearchTree(TreeNode root)
{
return IsValid(root, long.MinValue, long.MaxValue);
}
private static bool IsValid(TreeNode node, long min, long max)
{
if (node == null)
{
return true;
}
if (node.Value >= max || node.Value <= min)
{
return false;
}
return IsValid(node.Left, min, node.Value) && IsValid(node.Right, node.Value, max);
}
where TreeNode
public class TreeNode
{
public int Value;
public TreeNode Left;
public TreeNode Right;
public TreeNode(int value)
{
Value = value;
}
}
here's the detailed explanation https://codestandard.net/articles/validate-binary-search-tree/
Using inOrder Traversal..
First Adding the tree value to the array with inorder traversal.
Then iterate through the array which add a flag value true to split the elements after the root elements and before the root elements.
counter is added to check if the tree has elements with the same root value.
min and max is set to the range
var isValidBST = function(root)
{
if(!root) return false;
let current = root;
let data = [];
let flag = false;
let counter = 0;
function check(node){
if(node.left){
check(node.left);
}
data.push(node.val);
if(node.right){
check(node.right);
}
}
let min = Number.MIN_SAFE_INTEGER;
let max = root.val;
for(let i = 0; i < data.length; i++){
if(data[i] == root.val){
flag = true;
counter++;
}
if(flag){
if(data[i] < root.val || data[i] < max || counter > 1){
return false;
}
else{
max = data[i];
}
}
else{
if(data[i] > root.val || data[i] <= min|| counter > 1){
return false
}
else {
min = data[i]
}
}
}
return true;
};
We have to recursively ask each node if its left branch and right branch are valid binary search trees. The only thing each time we ask, we have to pass correct left and right boundaries:
class Solution:
def is_bst(self,root:TreeNode):
if not root:
return True
# left and right are boundaries
def dfs(node,left,right):
if not node:
return True
if not (node.val>left and node.val<right):
return False
# when we move right, we update the left, when we move left we update the right
return dfs(node.left,left,node.val) and dfs(node.right,node.val,right)
return dfs(root, float("-inf"), float("+inf"))
Here is the iterative solution without using extra space.
Node{
int value;
Node right, left
}
public boolean ValidateBST(Node root){
Node currNode = root;
Node prevNode = null;
Stack<Node> stack = new Stack<Node>();
while(true){
if(currNode != null){
stack.push(currNode);
currNode = currNode.left;
continue;
}
if(stack.empty()){
return;
}
currNode = stack.pop();
if(prevNode != null){
if(currNode.value < prevNode.value){
return false;
}
}
prevNode = currNode;
currNode = currNode.right;
}
}

Resources