Facebook Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: Phone Interview
/* check for BST */
private static boolean isBST(BSTNode root) {
if (root == null)
return true;
if (root.getLeft() != null && findMax(root.getLeft()) > root.getData())
return false;
if (root.getRight() != null
&& findMin(root.getRight()) < root.getData())
return false;
if (!(isBST(root.getLeft())) || (!isBST(root.getRight())))
return false;
return true;
}
boolean isBST(TreeNode node,int min,int max)
{
if(node==null)
return true;
if(node.leftchild==null && node.rightchild==null)
return true;
else if(node.value>min&&node.value<max)
return(isBST(node.leftchild, min, node.value)&&isBST(node.rightchild,node.value,max));
else
return false;
}
This is a best solution, only 2 nodes are compared in each pass instead of all nodes in both subtrees.
there is a minor bug the leftchild and rightchild being null doesnt make it BST because its own value needs to be checked so remove the 2nd if statement
Somebody has already made excellent point "If the inorder traversal of the tree is sorted, the tree is BST else not."
Didn't get why people are still trying for other implementations?
I guess the normal recursion, with two variable for allowed min and max would be sufficient for this question.
Following is the fully working code for the same.
#include <iostream>
#define INT_MAX 100000
#define INT_MIN -1
using namespace std;
class Node {
public:
int val;
Node * left;
Node * right;
Node() {val = -1; left = right = NULL; }
Node(int x) {val = x; left = right = NULL; }
~Node() {
delete left; delete right;
}
};
bool isBST(Node * root, int max, int min) {
if(root == NULL) {
// cout << "null, returning true \n";
return true;
}
cout << "At " << root ->val << endl;
bool condition = (root -> left)? (root -> left -> val < root -> val) : true;
condition = condition && ((root -> right) ? (root -> right -> val > root -> val): true);
condition = condition && (root -> val < max && root -> val > min);
if(condition == false) {
// cout << "condition not met at " << root -> val << endl;
return false;
}
return condition &&
(isBST(root -> left, root -> val, min)) &&
(isBST(root -> right, max, root -> val));
}
int main () {
// Construction a Binary tree;
Node * a = new Node(10);
Node * b = new Node(5);
Node * c = new Node(20);
Node * d = new Node(1);
Node * e = new Node(9);
Node * f = new Node(15);
Node * g = new Node(12);
Node * h = new Node(17);
Node * i = new Node(25);
a -> left = b;
a -> right = c;
b -> left = d;
b -> right = e;
c -> left = f;
f -> left = g;
f -> right = h;
c -> right = i;
cout << isBST(a, INT_MAX, INT_MIN) << "\n";
delete a;
return 0;
}
@Swapnil/Urik - Will this fix my code
bool isValidBST(struct node *root)
{
static struct node *prev = NULL;
if(root==NULL)
return true;
return isValidBST(root->left);
if(prev && root->data<=prev->data)
return false;
prev = root;
return isValidBST(root->right);
}
Sorry, below is the correct pheudo code, previous is a wrong post
boolean isBST (TreeNode node){
if(node == null) return true;
if (node.right == null && node.left == null) return true;
if(node.leftchild == null) {
if (node < node.right)
return isBST(node.rightchild);
else return false;
}
if(node.rightchild== null) {
if (node >node.left) return isBST(node.leftchild);
else return false;
}
return (isBST(node.rightchild) && isBST(node.leftchild));
}
non-recursion implementation:
public static boolean isBST_iterative(BST node) {
if(node == null)
return true;
List<BST> stack = new ArrayList<BST>();
List<Integer> values = new ArrayList<Integer>();
stack.add(node);
values.add(Integer.MIN_VALUE);
values.add(Integer.MAX_VALUE);
while(stack.size() > 0) {
BST bst = stack.remove(stack.size()-1);
int high = values.remove(values.size()-1);
int low = values.remove(values.size()-1);
if(bst.value > high || bst.value < low)
return false;
// left child
if(bst.left != null) {
stack.add(bst.left);
values.add(low);
values.add(bst.value);
}
if(bst.right != null) {
stack.add(bst.right);
values.add(bst.value);
values.add(high);
}
}
return true;
}
boolean isBST(TreeNode node) {
if(node == null)
return true;
if(node.left == null || node.right == null) {
if(node.left != null)
return (node.value > node.left.value) && isBST(node.left);
else if(node.right != null)
return (node.value < node.right.value) && isBST(node.right);
else
return true;
}
return isBST(node.left) && isBST(node.right);
}
Just fix a small issue in my previous code.
boolean isBST(TreeNode node) {
if(node == null)
return true;
if(node.left == null || node.right == null) {
if(node.left != null)
return (node.value > node.left.value) && isBST(node.left);
else if(node.right != null)
return (node.value < node.right.value) && isBST(node.right);
else
return true;
}
return (isBST(node.left) && node.value > node.left.value) &&
(isBST(node.right) && node.value < node.right.value);
}
#include <stdio.h>
#include <stdlib.h>
class Node
{
private:
int value;
Node *left,*right;
public:
Node(int nValue,Node * nLeft, Node *nRight)
{
this->value = nValue;
this->left = nLeft;
this->right = nRight;
}
Node * leftChild()
{
return left;
}
Node * rightChild()
{
return right;
}
int data() {return value;}
};
// If the root is root of BST returns the last node in the BST, else NULL
Node* isBST(Node * root,Node * predecessorNode)
{
if(!root)
{
return predecessorNode;
}
Node * predecessorOfRoot;
if(root->leftChild())
{
if((predecessorOfRoot = isBST(root->leftChild(),predecessorNode)) == NULL)
return NULL;
}
else
predecessorOfRoot = predecessorNode;
if(predecessorOfRoot && predecessorOfRoot->data() > root->data())
return NULL;
return isBST(root->rightChild(),root);
}
bool isBST(Node * root)
{
return root == NULL || isBST(root,NULL);
}
int main()
{
Node * root = new Node (8,
new Node(6,
new Node(4,NULL,NULL),
new Node(7,NULL,NULL)
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
Node * root2 = new Node (8,
new Node(6,
new Node(12,NULL,NULL),
new Node(7,NULL,NULL)
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
Node * root3 = new Node (8,
new Node(6,
new Node(4,NULL,NULL),
NULL
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
puts((isBST(root)?"BST\n":"Not BST\n"));
puts((isBST(root2)?"BST\n":"Not BST\n"));
puts((isBST(root3)?"BST\n":"Not BST\n"));
}
#include <stdio.h>
#include <stdlib.h>
class Node
{
private:
int value;
Node *left,*right;
public:
Node(int nValue,Node * nLeft, Node *nRight)
{
this->value = nValue;
this->left = nLeft;
this->right = nRight;
}
Node * leftChild()
{
return left;
}
Node * rightChild()
{
return right;
}
int data() {return value;}
};
// If the root is root of BST returns the last node in the BST, else NULL
Node* isBST(Node * root,Node * predecessorNode)
{
if(!root)
{
return predecessorNode;
}
Node * predecessorOfRoot;
if(root->leftChild())
{
if((predecessorOfRoot = isBST(root->leftChild(),predecessorNode)) == NULL)
return NULL;
}
else
predecessorOfRoot = predecessorNode;
if(predecessorOfRoot && predecessorOfRoot->data() > root->data())
return NULL;
return isBST(root->rightChild(),root);
}
bool isBST(Node * root)
{
return root == NULL || isBST(root,NULL);
}
int main()
{
Node * root = new Node (8,
new Node(6,
new Node(4,NULL,NULL),
new Node(7,NULL,NULL)
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
Node * root2 = new Node (8,
new Node(6,
new Node(12,NULL,NULL),
new Node(7,NULL,NULL)
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
Node * root3 = new Node (8,
new Node(6,
new Node(4,NULL,NULL),
NULL
),
new Node(12,
new Node(10,NULL,NULL),
new Node(14,NULL,NULL)
)
);
puts((isBST(root)?"BST\n":"Not BST\n"));
puts((isBST(root2)?"BST\n":"Not BST\n"));
puts((isBST(root3)?"BST\n":"Not BST\n"));
}
public boolean isBST(Node node) {
List<Integer> lst = new LinkedList<Integer>();
getInOrder(node, lst);
for (int i = 1; i < lst.size() - 1; i++) {
if (lst.get(i) < lst.get(i - 1)) {
return false;
}
}
return true;
}
public void getInOrder(Node node, List<Integer> values) {
if (node == null)
return;
getInOrder(node.left, values);
values.add(node.value);
getInOrder(node.right, values);
}
bool isBST(TreeNode * root, int min, int max, int &depth)
{
if (!root){
depth = 0;
return true;
}
if (root->val < min || root->val > max){
return false;
}
int ldep, rdep;
if (isBST(root->left, min, root->val, ldep) && isBST(root->right, root->val, max, rdep))
{
if ((ldep - rdep) <= 1 && (ldep - rdep) >= -1)
{
depth = 1+ max(ldep, rdep);
return true;
}
}
return false;
}
bool IsValidBST(TreeNode * root, TreeNode * & pre) {
if (root == NULL) return true;
if (!IsValidBST(root->left, pre)) return false;
if (pre != NULL && pre->val >= root->val) return false;
pre = root;
if (!IsValidBST(root->right, pre)) return false;
return true;
}
bool IsValidBST(TreeNode * root) {
TreeNode * pre = NULL;
return IsValidBST(root, pre);
}
bool isValidBST(struct node *root)
{
static struct node *prev = NULL;
if(root==NULL)
return true;
isValidBST(root->left);
if(prev && root->data<=prev->data)
return false;
prev = root;
isValidBST(root->right);
}
Basically its not checking whether the values returned by
isValidBST(root->left); and isValidBST(root->right);
are true or false, and hence if in case it returns false, we are not able to find that out.
@Swapnil - I think this condition
if(prev && root->data<=prev->data)
return false;
will take care of that
@Anon, Swapnil is right. You aren't propagating truth value up the tree.
bool isValidBST(struct node *root)
{
static struct node *prev = NULL;
if(root==NULL) return true;
if(!isValidBST(root->left) || (prev && root->data<=prev->data)) return false;
prev = root;
return isValidBST(root->right);
}
@Swapnil, Check above please.
@urik - Don't think your logic works. Where are you checking if isValidBST(root->right) returns true or false.
@Swapnil/Urik - Will this fix my code?
bool isValidBST(struct node *root)
{
static struct node *prev = NULL;
if(root==NULL)
return true;
return isValidBST(root->left);
if(prev && root->data<=prev->data)
return false;
prev = root;
return isValidBST(root->right);
}
@Matt, the last return statement funnels it upstream.
@Anon, your code will never go past the second return statement (the first naked out, meaning not surrounded by if statement).
- Vir Pratap Uttam May 05, 2015