Microsoft Interview Question for Software Developers


Country: United States
Interview Type: In-Person




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

Method1: Put inorder traversal in an array. Traverse the array changing right pointers and setting left pointers to null.

Method2: Start from root. Until current root has left children, rotate right about the root. (After rotating right, current root is the left child of previous root). If current root has no left child, traverse in the right subtree until you find a node which has a left child. Repeat the rotation. Once you reach a leaf when traversing down right subtree, stop.

- Noobie July 16, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

O(n) complexity and O(log n) memory assuming the tree's balanced:

static class Node{
    int value;
    Node left, right;
}

public static Node flattenTree(Node root){
    if(root == null){
        throw new NullPointerException();
    }
    
    Node[] flatten = flatten(root);
    return node[0];
}

private static Node[] flatten(Node node){
    if(node.left != null){
        Node[] leftResult = flatten(node.left);
        node.left = null;
        if(node.right != null){
            Node[] rightResult = flatten(node.right);
            leftResult[1].right = node;
            node.right = rightResult[0];
            leftResult[1] = rightResult[1];
            return leftResult;
        }
        else{
           leftResult[1].right = node;
           leftResult[1] = node;
           return leftResult;
        }
    }
    else if(node.right != null){
        Node[] rightResult = flatten(node.right);
        node.right = rightResult[0];
        rightResult[0] = node;
        return rightResult;
    }
    return new Node[]{node, node};
}

- zortlord July 16, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

you can Traverse the BST in In-Order this will give the element in descending order.

- kamal July 16, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

class Node {
public:
  int val;
  Node *left, *right;
  Node(int v) :val(v), left(nullptr), right(nullptr) {};
};

Node* flat(Node *root) {
  if (!root) return root;
  Node *start = root, *p = root, *tmp = nullptr;
  while (start->left) start = start->left;
  while (p) {
    if (!p->left) { p = p->right; continue; }
    tmp = p->left;
    while (tmp->right) tmp = tmp->right;
    tmp->right = p;
    p->left = nullptr;
    p = tmp;
  }
  return start;
}

- Eidn July 17, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

class Node {
public:
  int val;
  Node *left, *right;
  Node(int v) :val(v), left(nullptr), right(nullptr) {};
};

Node* flat(Node *root) {
  if (!root) return root;
  Node *start = root, *p = root, *tmp = nullptr;
  while (start->left) start = start->left;
  while (p) {
    if (!p->left) { p = p->right; continue; }
    tmp = p->left;
    while (tmp->right) tmp = tmp->right;
    tmp->right = p;
    p->left = nullptr;
    p = tmp;
  }
  return start;
}

- Anonymous July 17, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void flatten(TreeNode root) {	        
		  helper (root);
	  }
	  
	    private TreeNode helper (TreeNode root){
		  if (root == null) {
			  return null ;
		  }
		  if (root.left == null && root.right == null) {
			  return root ;
		  }
		  TreeNode left = helper (root.left);
		  TreeNode right = helper (root.right);
		  root.right = left ;
		  TreeNode p = root ;
		  while (p != null && p.right != null) {
			  p = p.right ;
		  }
		  if (p != null) {
			  p.right = right ;
		  }
		  root.left = null ;
		  return root ;

}

- Scott July 17, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public void flatten(TreeNode root){
	if(root == null){
		return;
	}
	Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
	while(root != null && !stack.isEmpty){
		if(root.left != null){
			if(root.right != null){
				stack.push(root.right);
			}
			root.right = root.left;
			root.left == null;

		} else{
            if(!stack.isEmpty()){
            	TreeNode temp = stack.pop;
            	root.right = temp;
            }
		}
		root = root.right;
	}

}

- deepak.bitp July 20, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

//Used an inorder traversal to visit the nodes in the tree. When visited, a node's left child is removed and the node is added to a stack
//O(n) time O(1) Space

public class Node 
{
	int value;
	Node left;
	Node right;
	
	public Node(int v)
	{
		value=v;
	}
}

public class BSTService
{
	public static Node flattenTree(Node n) throws NullPointerException
	{
		if(n==null)
		{
			throw new NullPointerException("input tree cannot be null");
		}
		Stack s=new Stack();
			flatten(s,n);
	}
	private void flatten(Stack s,Node r)
	{
		if(r==null)
		{
			return void;
		}
		flatten(s,r.left);
		if(s.isEmpty())
		{
			r.left=null;
			s.push(r);
		}else
		{
			r.left=null;
			s.peek.right=r;
			s.push(r);
		}
		flatten(s,r.right);
	}
	
	public static void main(String[] args)
	{
		Node n=new Node(24);
		Node l1=new Node(18);
		n.left=l1;
		l1.left=new Node(16);
		l1=l1.left;
		l1.right=new Node(17);
		Node r1=new Node(30);
		n.right=r1;
		r1.left=(26);
		r1.right=(34);
		r1=r1.right;
		r1.right=new Node(35);
		
		Node n=BSTService.flattenTree(n);
	}
}

- divm01986 July 20, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

The first solution is a somewhat naive recursive attempt. Because flattenTree returns the root of the flattened tree, and we need to add the current node as a child of the only leaf node in the flattened tree, we have to traverse the left result each time.

That makes this worst case O(n^2).

Node flattenTree(Node n) {
	if (n == null)
		return n;
	
	if (n.Left == null && n.Right == null)
		return n;

	var leftResult = flattenTree(n.Left);

	var m = leftResult;
	if (m != null) {
		while (m.Right != null) {
			m = m.Right;
		}
		m.Right = n;
		n.Left = null;
		n = leftResult;
	}

	n.Right = flattenTree(n.Right);
}

The second solution attempts to get rid of the extra unnecessary traversals by returning both the root and leaf node in the result of a helper method which recurses. This one is O(n).

private class Flattener {
	
	public static Node flattenTree(Node n) {
		var result = flatten(n);
		if (result == null)
			return null;
		return result.First;
	}

	private class FlatResult {
		Node Root;
		Node Leaf;
	}

	private static FlatResult flatten(Node n) {
		if (n == null)
			return null;

		if (n.Left == null && n.Right == null){
			return new FlatResult { Root = n, Leaf = n };
		}

		var leftResult = flatten(n.Left);

		if (leftResult != null) {
			leftResult.Leaf.Left = n;
			n = leftResult.Root;
		}

		var leaf = null;
		var rightResult = flatten(n.Right);
		if (rightResult != null) {
			n.Right = rightResult.Root;
			leaf = rightResult.Leaf;
		}

		return new FlatResult { Root = n, Leaf = leaf }
	}
}

- erika.r July 21, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class TreeNode
{
	public TreeNode() : this(0) { }

	public TreeNode(int value)
	{
		Value = value;
		Left = null;
		Right = null;
	}

	public int Value;
	public TreeNode Right;
	public TreeNode Left;
}


public TreeNode FlattenTree(TreeNode root)
{
	if (root == null)
		return null;

	TreeNode header = new TreeNode();
	TreeNode p = header;
	Stack<TreeNode> stack = new Stack<TreeNode>();
	stack.Push(root);

	while (stack.Count > 0)
	{
		TreeNode node = stack.Pop();
		if (node.Left == null && node.Right == null)
		{
			p.Right = node;
			p = node;
		}
		else
		{
			if (node.Right != null)
				stack.Push(node.Right);

			stack.Push(node);

			if (node.Left != null)
				stack.Push(node.Left);

			node.Left = node.Right = null;
		}
	}

	return header.Right;
}

- hnatsu July 22, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1 Find the left most node (this will be the root of the flattened tree)
2. rotate right
3. flattern right sub tree
4. return to parent node and repeat from step 2
Optimization : Keep a pointer to the leafNode of the flatterned subtree

Here is the C# implementation

public static TreeNode Flattern(TreeNode bst)
{
	//The Flatterned Tree
	TreeNode flattenedBST = null;
	//The leaf node of the flatterned tree. For Optimization
	TreeNode flatternedLeafNode = null;

	return Flattern(bst, ref flattenedBST, ref flatternedLeafNode);
}

private static TreeNode Flattern(TreeNode bst, ref TreeNode flattenedBST, ref TreeNode flatternedLeafNode)
{
	if (bst == null)
	{
		return bst;
	}

	if (bst.left != null)
	{
		flattenedBST = Flattern(bst.left, ref flattenedBST, ref flatternedLeafNode);
		flatternedLeafNode.right = bst;
	}
	else if (bst.left == null) 
	{
		if (flattenedBST == null)
		//This is the smallest in the whole tree, which is the root of the flattened tree
		{
			flattenedBST = bst; 
		}
		else 
		//this is the next smallest node
		{
			flatternedLeafNode.right = bst;
		}
	}
	//Set the last element in the partially flattned tree
	flatternedLeafNode = bst;

	//We have processed the left sub tree now
	bst.left = null; 
	Flattern(bst.right, ref flattenedBST, ref flatternedLeafNode);

	return flattenedBST;
}

- IC September 11, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Slightly modified in-order traversal can do it in O(n) complexity and O(1) space

class BSTFlattenRight
{
	public static void main(String[] st)
	{
		BTNode n1=new BTNode(1);
		BTNode n2=new BTNode(2);
		BTNode n3=new BTNode(3);
		BTNode n4=new BTNode(4);
		BTNode n6=new BTNode(6);
		BTNode n7=new BTNode(7);
		BTNode n10=new BTNode(10);
		BTNode n11=new BTNode(11);
		BTNode n14=new BTNode(14);
		BTNode n15=new BTNode(15);
		
		n1.right=n2;
		n3.left=n1;
		n3.right=n6;
		n6.left=n4;
		n6.right=n7;
		n10.left=n3;
		n10.right=n14;
		n14.left=n11;
		n14.right=n15;
		
		System.out.println("tree before:");
		in_order(n10);
		System.out.println();
		
		BSTFlattenRight obj=new BSTFlattenRight();
		BTNode root=obj.flat(n10);
		print(root,"after transformation");
	}
	
	static void in_order(BTNode node)
	{
		if(node.left!=null)
			in_order(node.left);
		System.out.print(node.data+", ");
		if(node.right!=null)
			in_order(node.right);
	}
	static void print(BTNode node,String msg)
	{
		System.out.println(msg);
		while(node!=null){
			System.out.print(node.data+", ");
			node=node.right;
		}
		System.out.println();
	}
	BTNode presentRightMost=null;
	BTNode flat(BTNode node)
	{
		BTNode parent;
		if(node.left==null)
			parent=node;
		else
			parent=flat(node.left);
		if(presentRightMost!=null)
		{
			presentRightMost.right=node;
			presentRightMost=null;
		}
		if(node.right==null)
			presentRightMost=node;
		else
			node.right=flat(node.right);
		return parent;
	}

}

- kandarp2516 October 13, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

using the next class which saves the root and leaf of each flatten BST :

public class NewTree {
	TreeNode head;
	TreeNode tail;
	
}

public class FlattenTree {
	public static void test()
	{
		System.out.println("Original:");
		TreeNode t= AssortedMethods.randomBST(5, 1,12);
		t.print();
		System.out.println("Flattened:");

		t=flatten(t);
		t.print();
	}

	private static TreeNode flatten(TreeNode t) {
		NewTree nt = flattenUtil(t);
		return nt.head;
	}

	private static NewTree flattenUtil(TreeNode t) {
		if(t==null)
			return null;
		NewTree left = flattenUtil(t.left);
		NewTree right = flattenUtil(t.right);
		NewTree ans = new NewTree();
		
		if(left!=null){
			ans.head=left.head;
			left.tail.right=t;
			t.left=null;
		}
		else
			ans.head=t;
		if(right!=null){
			ans.tail=right.tail;
			t.right= right.head;
		}
		else
			ans.tail=t;
		return ans;

	}
}

- idan.nik October 18, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Traverse down the tree to find leaf nodes, once leaf nodes are available, put the root node all the way to the right of the left leaf and return the left leaf as the new root.

Node Flatten(Node root)
{
	if(root == null)
		return null;
	if(root.left == null && root.right == null)
		return root;

	Node left = Flatten(root.left);
	Node right = Flatten(root.right);

	root.right = right;

	if(left != null)
	{
		Node tmp = root;
		Node tmp2 = left;
		while(tmp2.right) tmp2 = tmp2.right;
		tmp2.right = tmp;
		tmp.left = null;
	}
	return left;
}

- M October 27, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Approach : Using Inorder traversal...
1. Flatten the left subtree.
2. Flatten the right subtree.
3. Set the rightnode of root to flattened rightsubtree
4. Iterate through the flattened left subtree till the last element.
5. Set the right node of last element to root.

code

public BSTNode<T> flattenBinarySearchTree(BSTNode<T> root){
        if(root == null){
            return null;
        }
        if(root.getLeftNode() == null && root.getRightNode() == null){
            return root;
        }
        BSTNode<T> leftResult = flattenBinarySearchTree(root.getLeftNode());
        root.setRightNode(flattenBinarySearchTree(root.getRightNode()));
        BSTNode<T> currentNode = leftResult;
        while(currentNode!=null && currentNode.getRightNode()!=null){
            currentNode = currentNode.getRightNode();
        }
        currentNode.setRightNode(root);
        return leftResult;
    }

- nilesh.d.agrawal November 29, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Can I rephrase the question? Traverse the tree and print out all the elements. That will flatten the tree into a linear array. A BST with only right children can be thought of as a linear.
For the example mentioned in the question, we can do a in-order traversal and get the desired result.

- puneet.sohi July 16, 2015 | 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