Microsoft Interview Question for Software Engineer / Developers


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
4
of 4 vote

leetcode . com / 2010 / 11 / largest-binary-search-tree-bst-in.html

- hint February 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

yes he has explained properly under bottom-up approach while comparing to other approaches

So the logic is... while going bottom up(stack unwinding) you pass min and max at current node to the caller node(parent) and return the total number of nodes if its BST else -1. Nodes who does not satisfy the BST properties, all subtrees above them (which includes this node as well) must also not satisfy the BST requirements. Time complexity O(n) with no extra space

This c++ code is from the same page

int findLargestBSTSubtree(BinaryTree *p, int &min, int &max,
                   int &maxNodes, BinaryTree *& largestBST) {
  if (!p) return 0;
  bool isBST = true;
  int leftNodes = findLargestBSTSubtree(p->left, min, max, maxNodes, largestBST);
  int currMin = (leftNodes == 0) ? p->data : min;
  if (leftNodes == -1 ||
     (leftNodes != 0 && p->data <= max))
    isBST = false;
  int rightNodes = findLargestBSTSubtree(p->right, min, max, maxNodes, largestBST);
  int currMax = (rightNodes == 0) ? p->data : max;
  if (rightNodes == -1 ||
     (rightNodes != 0 && p->data >= min))
    isBST = false;
  if (isBST) {
    min = currMin;
    max = currMax;
    int totalNodes = leftNodes + rightNodes + 1;
    if (totalNodes > maxNodes) {
      maxNodes = totalNodes;
      largestBST = p;
    }
    return totalNodes;
  } else {
    return -1;   // This subtree is not a BST
  }
}

- vik February 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

For this piece of code, arent the conditions reversed?

if (leftNodes == -1 ||
     (leftNodes != 0 && p->data <= max))
    isBST = false;

And

if (rightNodes == -1 ||
     (rightNodes != 0 && p->data >= min))
    isBST = false;

Shouldnt they be "

//if data is greater than max or less than min then its not a bst


if (leftNodes == -1 ||
     (leftNodes != 0 && p->data <= min))
    isBST = false;

And

if (rightNodes == -1 ||
     (rightNodes != 0 && p->data >= max))
    isBST = false;

- PrateekS. August 01, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

We can divide the problem into several small problems:

1) For each node p, is the subtree with p as its root a binary search tree?
2) If it is a binary search tree, what is the size of the tree?

We can use recursion to do this:
Step1. for each node p, compute the minimum and maximum element of the subtree that rooted in p, as well as the size of the subtree.
Step 2. for each node p, check the maximum element of its left subtree and the minimum element of its right subtree to see if it is a BST, and if it is, sum up the size of the left right subtree and itself to get the size.
Step 3. Traversal the tree to find out the maximum BST as its subtree.

- leehomyc January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

/* Its difficult to understand what's going on in the code -- 
It is a divide an conquer..
Where we find the largest subtree in left.
And largest subtree in right.
and if root satisfies the BST property .. 
Take max of (3,Union(root, left, right)) ..

Union means joining the subtree's to the root if their heads are the children.
Here is the algo
Traverse Post Order.
At each Node 
    Base case -- if leaf  ----- return 1;
If BST property is satisfied at this node then.. 
     Add set the value to 3;
     if left is positive add it and subtract 1.
     if right is positive add it and subtract 1.
     Take max of left, right and current value. and return that.
else 
     Take absolute of left and right values. Then take the max between them.
      return the negative of this number.

In the end return the absolute of this answer.

The code only gives the size of the max tree. but easily we can augment this code 
to find out the tree. by keeping track of the current max tree and discarding the other.

We will have to destroy the tree. Other wise it will take exponential space.
But since one node can be a part of only one such candidate tree. Time complexity still remains O(n).

I have not written that code. because of lack of time.

typedef struct SearchTree {
    int val;
    struct SearchTree *l;
    struct SearchTree *r;
} bst;


int largestBSTIn(bst *head) {
    int l = 0, r = 0, h = 0;
    if (head->l == NULL && head->r == NULL)
        return 1;
    if (head->l)
        l = largestBSTIn(head->l);
    if (head->r)
        r = largestBSTIn(head->r);
    cout << "\n" << head->val << " " << l << " " << r;
    if ((head->l == NULL || head->l->val < head->val) && ((head->r == NULL) || head->val < head->r->val)) {
        h = (l > 0) ? (h + l) : h;
        h = (r > 0) ? (h + r) : h;
        h++;
        if (l < 0) {
            h++;
            l = -l;
            h = (h > l) ? h : -l;
        }
        if (r < 0) {
            h++;
            r = -r;
            h = (h > r) ? h : -r;
        }
    } else {
        if (l < 0) l = -l;
        if (r < 0) r = -r;
        h = -(l > r ? l : r);
    }
    return h;
}
int largestBST(bst *head) {
    int ans = largestBSTIn(head);
    return (ans > 0 ? ans : (-ans));
}

- isandesh7 January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

The idea here is traverse tree in inorder fashion and count the node and update the tree if it is BST. Checking for BST and counting the node can be done in same recursion for in order. It happens in one scan of tree and time complexity is O(n).
Here is the code.

// root is the inorder successor of prev, however we set prev to null if left subtree is not BST or root is less than prev. 
int isBST(Node* root, int *node_count, Node* prev, Node *currmax, int* max_count){
	if( root == null) {*node_count = 0; return 1;}
	
	int *lc; // node counter for left subtree
	int *rc; // node counter for right subtree
	int lf; // flag to test if left subtree is BST 
	int rf; // flag to test if right subtree is BST 
	int mf; // flag to test if root of right sub tree is greater than root 
	// NOTE : root is BST if all the the three flags are set 
	
	lf = isBST( root->left, node_count, prev, currmax, max_count);
	if( !lf ) prev = null;
	mf = 1;
	if( prev != null  && prev->data > root->data ) {
		mf = 0; 
		prev = null; 
	}
			
	prev = root;
	rf = isBST(root->right, node_count, prev, currmax, max_count);
	
	int flag = lf && rf && mf; 
	if(flag){
		int count = *lc + *rc + 1;
		if( count > *max_count ){
			currmax = root;
			*max_count = count; 
		}
	}
	return flag;
}

main(){
	Node * root = constructTree() // function that creates a tree and return the root;
	int *node_count = 0;
	Node* prev = null;
	Node* currmax = null;
	int* max_count = 0;
	
	
	isBST(root, node_count, prev, currmax, max_count);

}

- Anonymous January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I posted the isBST function. Sorry, I passed a parameter node_count that is not even used and ignore that while going through code.

- Prajwal Rupakheti January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

We can not do that For eg :

5
/ \
8 9
/ \
7 11

here in order traversal is 8 5 7 9 11

the largest subarray that is sorted is 5 7 9 11 however the max BST sub tree is rooted at 9 not at 5

- Prajwal Rupakheti January 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

In the above diagram 8 is left of 5, 7 is left of 9 and 11 is right of 9. Sorry for confusing diagram.

- Prajwal Rupakheti January 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Can we do a inorder travelsal of the tree - return as an array and the longest sorted portion of the array would be the largest BST in the binary tree

- hint January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

bottom up recursion

int min,max,no,tempmin,tempmax,largestno=-1;
node largest;
int largest(node root){
if(root==null) return 0;

int l=largest(root.left);
if(l!=-1&&l!=0){ tempmin=min;if(root.data<=max) return -1;}
else if(l==0) tempmin=root.data;
else return -1;

int r=largest(root.right);
if(r!=-1&&r!=0){ tempmax=max;if(root.data>=min) return -1;}
else if(r==0) tempmax=root.data;
else return -1;

min=tempmin;
max=tempmax;
no=1+l+r;
if(no>largestno) largest=root;
return no;
}

- zyfo2 February 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

if the subtree doesn't require containing all the subnodes

int no=0,max=-1;
node largest;
node largest(node root,int min,int max){
if(root==null){ no=0; return null;}

node l=largest(root.left,min,root.data);
node x=new node(root);
int tmp=no;
x.left=l;
x.right=largest(root.right,root.data,max);

if(root.data<max&&root.data>min){
no=tmp+no+1;
if(no>max) largest=x;
return x;}

no=0;
return null;
}

- zyfo2 February 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

int maxCount = 0;
TreeNode1* maxTree = NULL;

int LargestBSTSubtree(TreeNode1* root)
{
	// If empty node, return 0
	if(!root)
		return 0;

	// find the largest BST in left tree
	int left =  LargestBSTSubtree(root->left);
	
	// find the largest BST in left tree
	int right =  LargestBSTSubtree(root->right);

	// if either child is not a BST, this can be a BST
	if(left==-1 || right==-1)
		return -1;

	// verify if current node, holds BST properties
	if((root->left) && root->left->val > root->val)
		return -1;

	if((root->right) && root->right->val < root->val)
		return -1;

	// if all good, check if this is the largest
	if(maxCount<left+right+1)
	{
		maxCount = left+right+1;
		maxTree = root;
	}

	// return size of this valid BST
	return left+right + 1;
}

- Anonymous February 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 2 vote

/* Returns size of the largest BST subtree in a Binary Tree
  (efficient version). */
int largestBST(struct node* node)
{
  // Set the initial values for calling largestBSTUtil()
  int min = INT_MAX;  // For minimum value in right subtree
  int max = INT_MIN;  // For maximum value in left subtree
 
  int max_size = 0;  // For size of the largest BST
  bool is_bst = 0;
 
  largestBSTUtil(node, &min, &max, &max_size, &is_bst);
 
  return max_size;
}
 
/* largestBSTUtil() updates *max_size_ref for the size of the largest BST
   subtree.   Also, if the tree rooted with node is non-empty and a BST,
   then returns size of the tree. Otherwise returns 0.*/
int largestBSTUtil(struct node* node, int *min_ref, int *max_ref,
                            int *max_size_ref, bool *is_bst_ref)
{
 
  /* Base Case */
  if (node == NULL)
  {
     *is_bst_ref = 1; // An empty tree is BST
     return 0;    // Size of the BST is 0
  }
 
  int min = INT_MAX;
 
  /* A flag variable for left subtree property
     i.e., max(root->left) < root->data */
  bool left_flag = false;
 
  /* A flag variable for right subtree property
     i.e., min(root->right) > root->data */
  bool right_flag = false;
 
  int ls, rs; // To store sizes of left and right subtrees
 
  /* Following tasks are done by recursive call for left subtree
    a) Get the maximum value in left subtree (Stored in *max_ref)
    b) Check whether Left Subtree is BST or not (Stored in *is_bst_ref)
    c) Get the size of maximum size BST in left subtree (updates *max_size) */
  *max_ref = INT_MIN;
  ls = largestBSTUtil(node->left, min_ref, max_ref, max_size_ref, is_bst_ref);
  if (*is_bst_ref == 1 && node->data > *max_ref)
     left_flag = true;
 
  /* Before updating *min_ref, store the min value in left subtree. So that we
     have the correct minimum value for this subtree */
  min = *min_ref;
 
  /* The following recursive call does similar (similar to left subtree)
    task for right subtree */
  *min_ref =  INT_MAX;
  rs = largestBSTUtil(node->right, min_ref, max_ref, max_size_ref, is_bst_ref);
  if (*is_bst_ref == 1 && node->data < *min_ref)
     right_flag = true;
 
  // Update min and max values for the parent recursive calls
  if (min < *min_ref)
     *min_ref = min;
  if (node->data < *min_ref) // For leaf nodes
     *min_ref = node->data;
  if (node->data > *max_ref)
     *max_ref = node->data;
 
  /* If both left and right subtrees are BST. And left and right
     subtree properties hold for this node, then this tree is BST.
     So return the size of this tree */
  if(left_flag && right_flag)
  {
     if (ls + rs + 1 > *max_size_ref)
         *max_size_ref = ls + rs + 1;
     return ls + rs + 1;
  }
  else
  {
    //Since this subtree is not BST, set is_bst flag for parent calls
     *is_bst_ref = 0;
     return 0;
  }
}

- Nitin Gupta February 01, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think the following one is the optimum solution:

class TNode {
  public: //declare public for code simplicity
   int val;
  TNode *left, *right;
}

queue <TNode *> NQ;


int BST(TNode *r)
{
	if (r==NULL) return 0;
	if ((r->left==NULL) && (r->right==NULL)) return 1;
	if ((r->left==NULL) && (r->val>=r->right->val)) return 2;
	if ((r->right==NULL) && (r->val>=r->left->val)) return 2;
	if ((r->val<r->left->val) ||(r->val<r->right->val))  //Not a BST
	{
		NQ.add(r->left);
		NQ.add(r->right);
		return 0;
	}
	else return 3+BST(r->left)+BST(r->right);
}

TNode *Max(TNode *r){
	int max = 0, count = 0;
	TNode *tmp, *n;
	NQ.add(r);
	while (!NQ.empty())
	{
		n = NQ.front();
		NQ.pop();
		count = BST(n);
		if (count=>max)  //keep the first case alive
		{
			max = count;
			tmp = n;
		}
	}
	
	return tmp;
}
 

}

- Towhid February 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class LargestBSTSubTree {
	class BinaryTree {
		int data;
		BinaryTree left;
		BinaryTree right;
	}

	public BinaryTree findLagestSubTree(BinaryTree root) {
		BinaryTree largestBST = null;
		Integer min = Integer.MAX_VALUE;
		Integer max = Integer.MIN_VALUE;
		Integer maxNodes = Integer.MIN_VALUE;
		findLargestBSTSubTreeUtil(root, min, max, maxNodes, largestBST);
		return largestBST;
	}

	private int findLargestBSTSubTreeUtil(BinaryTree root, Integer min,
			Integer max, Integer maxNodes, BinaryTree largestBST) {
		if (root == null) {
			return 0;
		}
		boolean isBST = true;
		
		int leftBSTNodes = findLargestBSTSubTreeUtil(root.left, min, max,
				maxNodes, largestBST);
		int currMin = (leftBSTNodes == 0) ? root.data : min;
		if (leftBSTNodes == -1 || (leftBSTNodes != 0 && root.data <= max)) {
			isBST = false;
		}

		int rightBSTNodes = findLargestBSTSubTreeUtil(root.right, min, max,
				maxNodes, largestBST);
		int currMax = (rightBSTNodes == 0) ? root.data : max;
		if (rightBSTNodes == -1 || (rightBSTNodes != 0 && root.data >= min)) {
			isBST = false;
		}
		
		if (isBST) {
			min = currMin;
			max = currMax;
			int totalNodes = leftBSTNodes + rightBSTNodes + 1;
			if (totalNodes > maxNodes) {
				maxNodes = totalNodes;
				largestBST = root;
			}
			return totalNodes;
		} else {
			return -1;
		}
	}

	public static void main(String[] args) {

	}

}

- Kevin February 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

int largest(struct node*root){
int left,right;
if(root==NULL) return 0;
else if(root->left==NULL && root->right==NULL) return 1;
else{
left=largest(root->left);
right=largest(root->right);
if(root->left==NULL)
if(root->data<root->right->data)
return right+1+left;
else
return right;
else if(root->right==NULL)
if(root->data>root->left->data)
return left+1+right;
else
return left;
else if(root->data>root->left->data && root->data<root->right->data)
return left+right+1;
else return left>right?left:right;
}
}

- matrix1992 January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

int FindBST(struct Node *node,int min,int max,int &maxnodes,struct Node *& root,struct Node *& child)
{
if(node==NULL)
return 0;
if(node->data>min && node->data<max)
{
int leftnodes=FindBST(node->left,min,node->data,maxnodes,root,child);
struct Node *left=(leftnodes?child:NULL);
int rightnodes=FindBST(node->right,node->data,max,maxnodes,root,child);
struct Node *right=(rightnodes?child:NULL);

struct Node *parent=NewNode(node->data);
parent->left=left;
parent->right=right;

child=parent;

int count=leftnodes+rightnodes+1;
if(count>maxnodes)
{
maxnodes=count;
root=parent;
}
return count;
}
else
{
FindBST(node,-999,999,maxnodes,root,child);
return 0;
}
}

- Anonymous January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Can we do a inorder travelsal of the tree - return as an array and the longest sorted portion of the array would be the largest BST in the binary tree

- hint January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

We can not do that For eg :

5
/ \
8 9
    / \
   7 11

here in order traversal is 8 5 7 9 11

the largest subarray that is sorted is 5 7 9 11 however the max BST sub tree is rooted at 9 not at 5

- Prajwal Rupakheti January 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

can we say that the max BST is the BST with root node 5 ? does it violate BST definition ?
otherwise we may need to validate something more in the largest sorted array to know from where largest BST is starting

- hint January 31, 2013 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 vote

found the drawback in the algo

- S.Abakumoff January 31, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

forgot to note that the root of max bst is LCA of start node and end node, it's trivial to find it

- S.Abakumoff January 31, 2013 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More