Similar solution with some trival improvements.

call findPath function just once.

search the target Treenode from the beginning of two lists, because the time complexity of contains functions is O(n).

use label as a flag variable, which indicates when we can exit early.

public class LowestCommonAncestorBinaryTree {
LinkedList<TreeNode> stack = new LinkedList<>();
List<TreeNode> path1 = new ArrayList<>();
List<TreeNode> path2 = new ArrayList<>();
int label = 0;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
findPath(root, p, q);
int index = 0;
TreeNode result = null;
while(index < Math.min(path1.size(), path2.size())) {
if(path1.get(index) == path2.get(index)) {
result = path1.get(index);
} else {
break;
}
index++;
}
return result;
}
public void findPath(TreeNode root, TreeNode p, TreeNode q) {
if(label == 2) {
return;
}
stack.addLast(root);
if(root == p) {
label++;
path1.addAll(stack);
}
if(root == q) {
label++;
path2.addAll(stack);
}
if(root.left != null) {
findPath(root.left, p, q);
}
if(root.right != null) {
findPath(root.right, p, q);
}
stack.removeLast();
}
}