Microsoft Interview Question


Team: bing
Country: United States




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

can't have a worst case log(n) time method, because if the N nodes form a single branch, you still have N operations to do...

The code below is for O(N) time O(1) space. It does a depth first traversal from right to left while keeping track of the level depth and the deepest level reached. It outputs when the deepest level increases, meaning we are at a previously unvisited level and at the right-most element of it, that is, the max.

void print_level_maxes(Node* node, int& level, int& explored_levels )
{
    if (node)
    {
        if (level>explored_levels)
        {
            std::cout << "Max of level " << level << ":  " << node->key() << std::endl;
            explored_levels++;
        }
        ++level;
        print_level_maxes(node->right,level, explored_levels);
        print_level_maxes(node->left, level, explored_levels);
        level--;
    } 
}

int main()
{
int level = 0;
int explored = -1;
print_level_maxes(tree_root, level, explored)
return 0;
}

- oos September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

excellent!

- yemre_ankara September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Recursion uses implicit space: Omega(log n) and in the worst case, Theta(n).

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you please explain it-how it gonna work?

- Nish October 09, 2012 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

int arr[n];
int level=0;
int *find_max_per_level(int *p,int level){
    if(p==NULL) return arr;
    arr[level++]=p->data;
    if(p->right==NULL) p=p->left;
    else p=p->right;
    find_max_per_level(p,level);
}

- Shubham September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your approach might miss out on some lowermost levels.

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I could think of only O(logN)space O(N) time algorithm.

- Anonymous September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I am not sure if I got your question.
The rightmost child in a level will be the maximum element

- loveCoding September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Yes, but how do you get hold of the rightmost child at each level?

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You should be given the root element.
root->right is the max on level 1
root->right->right is the max on level 2
... and so on

- cypher September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It need not be a complete Binary Tree!

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You are right, i made an assumption here.
You can just do a breadth first traversal of the tree - O(n)

I don't think there is a O(log n) solution.

- cypher September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
-1
of 1 vote

seriously BFS in O(n)? I thought it is O(V+E)

- Vijay September 21, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

and i thought a tree with n nodes has (n-1) edges.
V+E = n+n-1 = 2n-1 so its O(n).

- Shubham September 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

To go with it there would be O(n) time as well
How to do it in given constraints?

- Tushar September 22, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

right boundary should give the maximum at each level.

right_boundary(node)
{
if(NULL == node)
{
return;
}

/* if there is right child, then move to right child */
if(node->right != NULL)
{
right_boundary(node->right);
}
else if(node->left != NULL) /* otherwise there is only left child */
{
right_boundary(node->left);
}
/* print key for the node */
print(node->key);

return;
}

- Anonymous September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

This will not work for the Tree:

100
                50         250
           20       75

- Ashupriya September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Supposed that we don't consider the space for BFS, we can do in O(n) time and O(1) for space.
we can do in the following way:
BST:

9
                                        7                             11
                           6                     8

9,7,11,6,8, for each level, the sequence should in a ascending order. Level i and Level i+1 will have a decrease, like 11->6. We can make use of this rule to print max of level i.

void printMaxByLevel ( Node * root)
{    
       if (root == NULL)
           return;
       queue<Node*> aux;
       aux.push(root);
       int max = root->key;
      int level = 0;
       while( !aux.empty( ) )
       {
             Node * current = aux.front();
             if (current < max)//Node Value  in BST right sub tree >Node Value  in BST left tree
             {
                        cout<<level<<"  "<< max << endl;
                        level++;
              }
              max = current->key;
              if (current->left != NULL)
                  aux.push (current->left);
              if (current->right != NULL)
                  aux.push (current->right);
        }
        //clean up, for the last node which is maximum node in the last level in the queue
        cout<<level<<" "<<max<<endl;
}

Advice welcome! thanks a lot.

- Anonymous September 20, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

there is a bug, where there is no left subtree.
you can put some decision on if(current->left!=NULL). if current->left==NULL&& current->right!=NULL) print max<<level

- Anonymous September 20, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

As already told here, we can keep track of each level while doing a BFS. At each level, we can see which is the max element.

int height2(TreeNode *root) {
  if (!root) return 0;
  queue<TreeNode*> nodesQueue;
  int nodesInCurrentLevel = 1;
  int nodesInNextLevel = 0;
  int nodes = -1;
  int maxAtCurrLevel = INT_MIN;
  nodesQueue.push(root);
  while (!nodesQueue.empty()) {
    TreeNode *currNode = nodesQueue.front();
    nodesQueue.pop();
    if (currNode->data > maxAtCurrLevel) 
      maxAtCurrLevel =  currNode->data;    // If value of current node greater than current maximum of this level
    nodesInCurrentLevel--;
    if (currNode) {
      cout << currNode->data << " ";
      nodesQueue.push(currNode->left);
      nodesQueue.push(currNode->right);
      nodesInNextLevel += 2;
    }
    if (nodesInCurrentLevel == 0) {
      nodes++;
      cout<<"\n";
      nodesInCurrentLevel = nodesInNextLevel;
      nodesInNextLevel = 0;
      cout<<"Maximum element at this level: "<<maxAtCurrLevel <<endl;
     maxAtCurrLevel  = INT_MIN: //level finished
    }
  }
  return nodes;
}

- catlover September 28, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

If I'm getting your solution correctly, you're pushing possibly all of the nodes in each level to a queue, and worst case the desired level is bottom level, so:
you have 1+2+4+8+...+[(n/2)+1] = n steps
and (n/2)+1 memory

- avico81 September 29, 2012 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

We can also have an array maxVal[height] which is sized according to the height of the tree. Each entry in the array represents the maximum value at the level. Pseudocode looks like this

void findMaxLevels(tree *root, int level, int *maxVal)
{
if (!root)
return;

findMaxLevels(root->left, level+1, maxVal);

maxVal[level] = (maxVal[level] > root->data ? maxVal[level] : root->data);

findMaxLevels(root->right, level+1, maxVal);
}

We can simply print the array maxVal to get the maximum value at each level.

- kill -9 October 01, 2012 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

void maxElement(TreeNode* root)
{
      queue < pair<TreeNode*, int> > q;
      int cLevel(0) , pLevel(0);
      TreeNode* cNode;
      if (root != NULL) { q.push( make_pair(root, 1) ); cLevel = 1; max_ele = root->val ; } 
      while (!q.empty()) {
          cNode = q.top().first;
          cLevel = q.top().second; q.pop(); 
          if (cLevel != pLevel) {
                    if (pLevel) cout << max_ele << endl;
                    else max_ele = cNode->val; 
          }
          else max_ele = max(max_ele, cNode->val); 
          pLevel = cLevel;
          if (cNode->left) q.push( make_pair(cNode->left, cLevel+1) );
          if (cNode->right) q.push( make_pair(cNode->right, cLevel+1) );
      } 
      if (cLevel) cout << max_ele << endl; 
}

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

An attempt for log N solution (for sure in best case, but unable to prove for worst case)

Algorithm:
curNode=root
while(true) {
 print curNode value if the level is not already processed, mark this level as done
 if (curNode->left) && (curNode->right) {
   stack.push(curNode->left);
   curNode=curNode->right;
 }
 else if (curNode) curNode=(curNode->left?curNode->left:curNode->right)
 if (!curNode && !stack.isEmpty() && notAllLevelsProcessed) curNode=stack.top(); stack.pop();
}

- IntwPrep December 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

In O(n) time and O(1) space : Morris traverse

- Anonymous September 21, 2012 | Flag Reply


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