Microsoft Tree Questions
Microsoft Tree Questions
""" '()*" +,
#
$%&"
G )/" %1"54%*)3
H
B353 AI9 C 1&)J#43 K
M-'
5
:=/5%58 $/"" L
AI9 C /"*=/'%2"
7N$O+ D)51%"' %5 :$ 0=4
%'45M=4%58
7J
B35 C 09 C /"=5%05
:$ 40 +FF
:,$ K' B3&45 C B3)49"C ,$N@
<"/8"
4E0
? <)P
()49'=&3-E4E03")-'
B99 0*9 C /"*"''%05
8%2"5
G01"' )4 ) 1%'4)5*" O(n) O(h) queue, unordered
map
M%5)/;
%5 ) 4/""
?
0- 8%2"5 0*9C
*0='%5' ) 501" B35C
E%49
-/0&
()49 504
? B35C AI9C
'("*%-%"1 '=&
O(n). O(h)
?
:0=51)/; $/)2"/')3 0-
:$ #
'=M4/""
All 4 variations of leetcode done.
-001'-4--0-01"
-/049
-0/&)4
501"' )4 ')&" >5""
-0/&)4%05
G01"' )4 1%'4)5*"
? ,"/%)3%'4 R +"'"/%)3%'" :$
#
1%)805)3 $/)2"/')3
0-
:$
D0=54
9)2%58 8%2"5
'=M4/""'
? H
./"0/1"/ $/)2"/')3 S
%4"/)4%2"
;0=
J UV @84
W
3"-4
#
J ,
! X R Y Z
If root is null and stack is still not empty i.e. you have
reached the leftmost end of your tree and now root is
pointing to null, time has come to make root as
whatever is on the top of your stack, which is the right
child of your parent or in simple words your sibling
Pop off the stack we no longer need that value on your
stack.
While the node is not null or stack is not empty in any of the
two cases, keep on running the while loop
If the node is not null then simply push that node onto the
stack and move left. i.e. c = c->left;
]]^^^]]]\\_
0
! [
S
\
.0'4 S 0/1"/ $/)2"/')3
`
501"
a
XR , Z ! ?
7"%894 0- M%5)/;
) 4/""
Swap left with right using a temporary variable, or we can even use the swap function of stl
7)c"3 +%'4/%M=4%58 *)51%"'
L %-
d S 1%'4)5*"
-/0& (04
/"*=/'%2" *)5'
e
#
-
E9"5 $">
-0/ 3"-4
5%894 E" (='9
?
@004 40 3")- ()49 '=&
O88
S
!1"54%*)3
a
504
+"4"/&%5" %- 4E0 4/""'
)/" 0/
7)/1
f-8 N10M" ?
g ing Tree N&)c05 L
-35(>)/4 <%*/0'0-4
L L
Store the front of queue into node and then check if the node’s
If node’s left exist then store node as node left’s data is equal to the node where fire takes place, if that is the case
Parent in the map. i.e. parent[node->left] = node; then you have to store this node in the resultant node.
Where you have a map<Node*> parent; we will pop this q.front() as we no longer need it.
Push node->left into the queue. Likewise check the same for right child of the node and update the parent details in
The map if node->right exist make parent[node->right] =node;
The Bfs does two things here, one it will store the node where fire takes place and secondly, we know know who is
who’s parent as everything is now present in your map. Return the resultant node at the end.
Now the findmaxdist function is called on the map and the burning node which we just found out.
The findmaxdist function will have a queue<Node*> q and we will push the burning node onto this queue, as our
bfs will begin from here only. So in this code, we have two bfs. We will store a visited map of Node*,int
We will set the visited[burningnode] =1 initially as it is the first node in the queue and it has already been visited.
at the end, check if flag=1 in any of the three cases, then you do a maxi++
Outside the while(!q.empty()) loop return the maxi;
L
L L
:%5)/;
$/"" 40 +FF
G - 9h iG
&
]U
Simply solve the problem by divide and conquer, solve the left
Subtree and then update the pointers as successor is the rightest
node in the left subtree and the root will be the root
Now successor->right will be root and root->left will be the
successor.
$%&" U 0j <45 C
'()*" L B j 7I 49)
C
You do not have to use an additional data structure to sort the data. Since the inorder traversal of a BST will give
you the elements of it in sorted order, you can simply traverse each BST, taking the lowest element from each as
you go. The following solution uses iterative inorder traversal and meets the time and space constraints of O(M+N)
time and O(Height of BST1 + Height of BST2).
%4U\ L
vector<int> merge(Node* root1, Node* root2) 2
{
stack<Node*> stk1,stk2;
vector<int> merged;
^U\
bool trav1 = true, trav2 = true;
while (root1 or root2 or !stk1.empty() or !stk2.empty())
k/054 l 4/0=4 4/="
4/)5'-='"
{
while (root1 && trav1) m
]^]]
{
stk1.push(root1);
root1 = root1->left; -/054S3%5"
}
while (root2 && trav2)
{ ? 4/)5'-"/
stk2.push(root2);
root2 = root2->left;
}
OJO
merged.push_back(root1->data); 6
root1 = root1->right;?
S
trav1 = true;
trav2 = false;
}
else
{
if (!root2)
break;
merged.push_back(root2->data);
root2 = root2->right;
trav1 = false; trav2 = true;
}
}
return merged;
}
};
<)P
()49
S
'=&
0- 4E0
3")-
501"'
%# o / U Y K
'"4
ZgI
Z 4U
)5' U p
3
$
S
3U
S
40
R R ,
/U
UH F
4 3 U '
='" SX
/ U ,
40 R %' R
FU
S
30 / U ;
? /U
S
40
We will store INT_MIN in result as we need to find the maximum path sum.
We will store ans = f(root, res) and then return ans If res doesn’t change and return
res if res changes to some value.
if root is null return 0, if both the left and right child are null then return root->data.
These would be our base cases for our recurrence.
Call the same function on root->left and store It in l and call the same function in
root->right and store it in r.
Now for every internal node, temp = max(ltr)+root->data and ans = l+r+root->data.
We will return temp.
For some node it is possible that their left child doesn’t exist but right child exist,
then in that case, we will check if root->left is NULL then we will store
Temp = r + root->data; and we will return temp
Likewise, if root->right doesn’t exist then temp = l + root->data and we will return
temp.
q)3&)/4
f-8 9)/1 &%*/0'0-4 )&)c05
M%5)/;
S
AA 8)&"' 89""
08
We will create a queue<TreeNode*> queue; and start pushing
root in it and while queue is not empty we will keep on storing
the parent[curr->left] = curr and before that curr = q.front();
and we will push curr->left into the queue and we will repeat
the same with node->right and store the parent[node->right] =
node; and then we will insert that into the queue.
At the end, queue will be empty and we have now stored the
parents of all the nodes.
The target node is given to us, and now we will insert the
target node into the queue and start the BFS again and keep
a counter count=0 and every time we enter into the while loop
iteration, we update the count++ and check if it is equal to k
we will break out of the while loop
Gfg solution is almost same, but will little changes as we have given the node value, not the node pointer. So we will create one
and while the bfs, we will find the node who’s value is same, we will update and we have to sort the vector before returning it.
501" 49"
0- 8%2"5
D0='%5' 501" U ) K' *0='%5 )/"
K
74 U,
0=4(=4 U '
L
;
AAA
#
class Solution We will make a vector v and a queue q and initially push the root
#
{ node onto the queue and then till q is not empty we will initialise
public: found as false and n=q.size(); and while(n—) we will set a local
vector<int> printCousins(Node* root, Node* x){ variable as false and store q.front() in node and pop off the q.
if(!root) return {}; Check if node->left exist then check if node->left is the node which
vector<int>v; we are seeking for who’s cousins we need to push, if that is the
queue<Node*>q; case then we will set local=true and found=true
q.push(root); push node->left in the queue.
while(!q.empty()){
int n=q.size(); Do the same thing for node->right if it exist then push it in the
bool found=false; queue and check if node->right==x then set local and found as
while(n--){ true.
bool local=false;
Node *node=q.front(); if local is false, and honestly saying we also want it to be false so
q.pop(); that we are able to find the cousins of the target node. Then we
if(node->left){ have to check
if(node->left==x){ If node->left exist push the node->left->data on the vector,
local=true;
found=true; do the same thing for node->right->data if node->right exist.
} Outside the while loop, if the found is still true, then we will break
q.push(node->left); and else we will clear the vector.
}
if(node->right){ at the end we will see found=true only if cousins are present
if(node->right==x){
local=true; If found is false, we have to return{-1} otherwise we will return v
found=true;
}
q.push(node->right);
}
if(!local){
if(node->left) v.push_back(node->left->data);
if(node->right)v.push_back(node->right->data);
}
}
if(found) break;
else v.clear();
}
if(v.empty()) return {-1};
return v;
}
};
.)49 -/0& /004 E%49
'("*%-%"1 '=&
d04
i
i
/)&%'
)11
#
T TT
# #
J
# T
T T )4
"88t
t
!5U41" 4=/5
1%81E)04
2)3 !
! u
S )5'
! ]o
S
XA
6vgXAZ )5' b
K
4%'
J 3
3 3 - w p 6!N
kJ! )583"
Boundary Level Traversal of binary Tree
E%33 1%2%1"
E"
x %540 Z
49%'
()/4'
'%1" 501"'
/004 3"-4
501"'
+5"(/ 3")-
l A /%894
T 501"'
'%1"
B
k'
We will create an empty vector v and pass it in all the three functions which are leftnodes, leaf nodes and rightnodes along with the
Node* root which is the root node. Firstly we will push the root node in the vector and then we will call the three functions in the
order given above. LeftNode(root->left, v) leafnodes(root, v), rightnodes(root->right, v) and return v at the end and the return type
of all the three functions will be void as we will be using call by reference.
For the leftnodes we check ki if the root is null or the node is a leaf node we will return. Then we will check ki if left of root exist and
right of root doesn’t exist then we will push the node in the vector and move left. Else case will handle ki right of root exist but left
doesn’t exist, then we will push the node and move right. In the leftNodes wala function we will push first and then depending on
the scenario of the above mentioned two cases we will either move left or right.
In the RightNodes cases, we will do the same shit, but we will first move left/right depending on the two scenarios and after that
we will push the node into the vector.
IN the leaf nodes case, we will check if the root does not exist, then we will return
And in the case, the root is the leaf node that is both of their left and right does not exist then we will push the node data into the
vector. And do a simple preorder traversal .
!
Leetcode Hard
Vertical Level Traversal
GFG Medium
Time: O(n)
Space: O(n)
We will create a queue of pair where the first will be Node and second will be value
Associated with the node. We will make a vector answer. If the root itself is null then
in that case, we return answer.
We create a map of integer key and vector<int> value and name it as m.
We push the pair(root,0) in the queue.
While the queue is not empty we store the first of front of the queue in temp i.e. the node is stored in temp and the value
associated with the node that is the second of the front of the queue, it is stored in h. We push the temp->data into the map at
#
key h. Now pop the queue front. Now check if temp->left exist, then push the temp->left, h-1 pair in the queue and if temp->right
exists then push temp->right, h+1 pair in the queue.
Now, for every element in the map, for every value in element’s second .ie. the vector push x.second[I] in the vector answer.
Return the answer in the end.
Construct Tree From Inorder and Preorder
Inorder list is [3,1,4,0,5,2] and preorder list is [0,1,3,4,2,5]. Now we will create a
map m of int,int where key is int and the value associated with it is integer too.
We will make a for loop and we will store data and the index associated with the
data into the map, key will be data and the index associated to it will be value.
After the for loop runs the map will be storing the inorder like this.
(0,3),(1,1), (2,5), (3,0), (4,2), (5,4)
Integer variable inleft will store the number of if(prestart exceeds pretend or instart exceeds inend) we return NULL. This will be
Elements belong to root->left which will be the base case of our recursion.
inroot-instart
In this case, inroot=3 as 0 is root->val and it is Integer variable inroot will store index where root->val is stored
Stored at index 3, we got these details from the map data structure which we have maintained. Now instart=0 so number of elements
to the left of root are 3-0 = 3.
Now we are ready for the two recursive calls. We have to assign the root->left and root->right
Root->left = f(pre, prestart+1, prestart+inleft, in, instart, inRoot-1,m)
Let me explain how this came, so simple first element of the pre is the root itself, so the left side will start from pre+1 index and we
have just calculated that the number of elements of the root->left are 3 i.e. inLeft, so the end point for root->left for pre list will be
pre+inLeft. Then we pass the inorder list as it is, and the instart will be instart as inorder list starts form there and the inorder list ends
is one index less where the root is present and the root is present at inRoot so the end point of inorder list will be inroot-1.
Leetcode has 4 variations of LCA, any of these variations can be asked in Microsoft so we should be prepared for the worst
case.
LCA II THE NODES MAY/MAYNOT EXIST P!=Q
CAN YOU FIND LCA TRAVERSING THE TREE, WITHOUT CHECKING THE NODES EXISTENCE?
We will do the Depth first search as we need to solve this question in one pass itself, and the DFS will return the LCA and count
If the count is less than 2 we return null pointer as one of the node or maybe both of the nodes are not present in the tree.
otherwise we will return the first of the pair that would be the LCA of the tree.
In the DFS function we will pass the root node, the node p and the node q and the base case will check whether the root exists or
not if the root does not exist in that case we will return nullptr,0 as the return type is pair<TreeNode*,int>
we will recursively call the DFS on root->left and root->right and store it in left_result and right result. And the return type of these
left_result and right_result is also pair<TreeNode*,int>
We will check that if the root=p or root=q then in that case we will return root,1+left_result.second+right_result.second as pair
If both of the left node and right node exist i.e. left_result.first exist and right_result.first exist then we return root,2
If both of these if statements give false, then return either of the left node or right node depending on their existence.
In the main method, call dfs(root,p,q) and store it result of pair<TreeNode*,int> and checking if the count / result.second<2 return
NULL and if not return the result.first which is the LCA of the tree.
LCA III Asked in Facebook Time: O(logn) Space O(logn)
Leetcode Premium
Approach is: As we have parent pointers given of each node, we will store the first node and all of its parent pointers in
the Hashmap and for the second node, we will start iterating and checking If it’s parent is present in the Hashmap or not.
We will return first such parent which is present in the Hashmap and that would be the LCA of the Binary Tree
As we are guaranteed that both of the nodes are present in the tree, then this is simple and the time complexity is O(logn)
and the space complexity is O(logn)
Second Approach says that it is like finding the first common nodes of two linked list.
LCA of Binary Tree IV
That’s all
Is SubTree GFG O(n) time and O(n) space
In the function to check whether tree s is the subtree of tree t, we need to check the base condition that if both of the trees are
null pointers then by definition of the null pointers, both of them are subtrees to each other so in that case, we need to return true.
Then we will check that if the tree node exists
Then we will check that if f(tbs) returns true or if s exists on the left subtree of t or s exists on the right side of t we return true.
Otherwise we return false.
Let us analyse function f.
If any of them is null and other one is not, then we return false.
If both of them have different data present then we return false.
We check recursively on left side on both t and s and right side on both t and s we return true.
if not, we return false.
Push the root in the queue then till the queue is not empty, assign
Ans as NULL. And until the size of queue becomes 0 store q.front
int cure and pop the front from the queue. Check if the current left
Exist push it in the queue, if right exist then push curr->right in the
queue. At last check if the ans remains null, then point and to curr.
If ans is not null then ans->next right will be pointing to where curr
is pointing and ans will be updated to its next right.
S
10
Next time for 3,5 q.size=2 for the first time ans=NULL so
ans will point to 3
Now when the inner while loop will run for the second time it will
Will be set and we keep on doing for every other level.
run the else black hence ans store 3 so 3->next right will be 5 as
This will be evident if you do the dry run.
Curr stores q.front which was 5 and we popped off 5 so this pointer
Time: O(n) Space: O(H) Flipkart, Microsoft
The function f is taking root and string s and returning the preorder
Traversal of the tree
Like for the above tree it will be ‘lrlrlrr’
If k=2 then we will call f on root and the vector of string will be lrlrlrr
res=0
For each character in string ret if string length is less then k then
Do nothing, continue. Else assign temp to root node
And for I=0 to s.size()-k we need to run this for loop and we will
check if s[I]=l then we willl go to left side using temp otherwise we
Will go to the right side using temp
and check if the node is not present in map, we insert it into map
And increment it’s count. And increase res by 1.
Time: O(n)
Serialise and Deserialise the Binary Tree
Space: O(n)
e '40/%58
%5
4/""
%5 /"*40/;
? '40/"
i
1=&&;
i& 8/)51"
#&5Uo
The serialise is easy, we need to store the inorder traversal of the binary tree and need to push that into the vector
The deserialise is also very simple we need to make a dummy node with value -1 and assign temp to that
And we will traverse this vector and keep on making right and that is how will will give entire tree.
'4/%58
40
)/"
-/""
8%2"5 ) R E" 5""1 *05'4/=*4
*052"/4 49" 4/""
)
M%5)/;
-/0&49"
%4 - 5""1 40
)8)%5
E"
M)*>
'4/%58
40 #
Space, Time: O(n)
Diagonal Traversal of Binary Tree 6
y
%54
2"*40/
%
501" n
(/00- i i
?
1s349 #
?
?i '40/" 2 #
i -/
q)4"/
B
6
z
)5; /"-"/"5*"
#
G
? 9"' '=&
4/""
*9"*> %- 3"-4
T
/%894
T
T
i
#
S
i %
# L
$$ _ !
#
T
k0/ T T
?
Tree from post order and inorder
(0'4"1 U /"-"/"5*"
)/10/ 8%-4 "%894 i (=5;
i
M)'" *)'" #
i 300>%5
$-
)4 3)'4 -(''40/1"8
&%1
J-{&]k%894
#
?
%
{iG|4uf
4
.0'40/1"/ U p X Y RZ
9)/1"/ X p ! Z Y
R
!51"P B 3 X Z J ,
350/1"0
49" 1)4)
;'40;"35&1)s"P*0//#40
5
{
-=5 .0 Y# C
`
&
}
XC *)33
0
L L5 L L
K T
T
80 #
l
K
t
#