So, I don't know if someone else out there is as confused as I was when he/she is stuck on test case 31. The code cruised over the first 30 out of 31 test cases and failed on this one. This was my code:

```
public class Solution {
TreeNode LCA;
boolean found;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
LCA = null;
found = false;
traverse(root, p, q);
return LCA;
}
private boolean traverse(TreeNode root, TreeNode p, TreeNode q) {
int counter = 0;
if (root.left != null && traverse(root.left, p, q)) counter ++;
if (found) return true;
if (root.right != null && traverse(root.right, p, q)) counter ++;
if (found) return true;
if (counter >= 2) {
LCA = root;
found = true;
return true;
}
if (root.val == p.val || root.val == q.val) counter ++;
if (counter >= 2) {
LCA = root;
found = true;
return true;
}
if (counter >= 1) return true;
return false;
}
}
```

To put it simple, my mistake was that I compared the values instead of the reference, and case 31 happens to have duplicate values.

```
public class Solution {
TreeNode LCA;
boolean found;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
LCA = null;
found = false;
traverse(root, p, q);
return LCA;
}
private boolean traverse(TreeNode root, TreeNode p, TreeNode q) {
int counter = 0;
if (root.left != null && traverse(root.left, p, q)) counter ++;
if (found) return true;
if (root.right != null && traverse(root.right, p, q)) counter ++;
if (found) return true;
if (counter >= 2) {
LCA = root;
found = true;
return true;
}
if (root == p || root == q) counter ++; // <=====changed here
if (counter >= 2) {
LCA = root;
found = true;
return true;
}
if (counter >= 1) return true;
return false;
}
}
```

The algorithm I used is pretty straightforward. If a node finds itself has both of the desired nodes as itself and/or it's children, store itself. The whole thing takes less or equal to one dfs pass. O(n) time complexity + O(1) space complexity. There we go.