Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions
Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions
Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Solutions</strong> to Chapter 4 | Trees <strong>and</strong> Graphs<br />
to check if <strong>the</strong> child node on this side is p or q (because in this case <strong>the</strong> current node is <strong>the</strong><br />
common ancestor). If <strong>the</strong> child node is nei<strong>the</strong>r p nor q, we should continue to search fur<strong>the</strong>r<br />
(starting from <strong>the</strong> child).<br />
If one of <strong>the</strong> searched nodes (p or q) is located on <strong>the</strong> right side of <strong>the</strong> current node, <strong>the</strong>n<br />
<strong>the</strong> o<strong>the</strong>r node is located on <strong>the</strong> o<strong>the</strong>r side. Thus <strong>the</strong> current node is <strong>the</strong> common ancestor.<br />
1 static int TWO_NODES_FOUND = 2;<br />
2 static int ONE_NODE_FOUND = 1;<br />
3 static int NO_NODES_FOUND = 0;<br />
4<br />
5 // Checks how many “special” nodes are located under this root<br />
6 int covers(TreeNode root, TreeNode p, TreeNode q) {<br />
7 int ret = NO_NODES_FOUND;<br />
8 if (root == null) return ret;<br />
9 if (root == p || root == q) ret += 1;<br />
10 ret += covers(root.left, p, q);<br />
11 if(ret == TWO_NODES_FOUND) // Found p <strong>and</strong> q<br />
12 return ret;<br />
13 return ret + covers(root.right, p, q);<br />
14 }<br />
15<br />
16 TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) {<br />
17 if (q == p && (root.left == q || root.right == q)) return root;<br />
18 int nodesFromLeft = covers(root.left, p, q); // Check left side<br />
19 if (nodesFromLeft == TWO_NODES_FOUND) {<br />
20 if(root.left == p || root.left == q) return root.left;<br />
21 else return commonAncestor(root.left, p, q);<br />
22 } else if (nodesFromLeft == ONE_NODE_FOUND) {<br />
23 if (root == p) return p;<br />
24 else if (root == q) return q;<br />
25 }<br />
26 int nodesFromRight = covers(root.right, p, q); // Check right side<br />
27 if(nodesFromRight == TWO_NODES_FOUND) {<br />
28 if(root.right == p || root.right == q) return root.right;<br />
29 else return commonAncestor(root.right, p, q);<br />
30 } else if (nodesFromRight == ONE_NODE_FOUND) {<br />
31 if (root == p) return p;<br />
32 else if (root == q) return q;<br />
33 }<br />
34 if (nodesFromLeft == ONE_NODE_FOUND &&<br />
35 nodesFromRight == ONE_NODE_FOUND) return root;<br />
36 else return null;<br />
37 }<br />
1 2 9<br />
<strong>Cracking</strong> <strong>the</strong> <strong>Coding</strong> <strong>Interview</strong> | Data Structures