class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
function lowestCommonAncestor(root: TreeNode | null, p: TreeNode, q: TreeNode): TreeNode | null {
if (root === null) return null;
if (root === p || root === q) return root; // found one target
const left = lowestCommonAncestor(root.left, p, q); // search left subtree
const right = lowestCommonAncestor(root.right, p, q); // search right subtree
if (left !== null && right !== null) return root; // targets found in both sides
return left !== null ? left : right; // return non-null child or null
}
// Build tree nodes
const node7 = new TreeNode(7);
const node4 = new TreeNode(4);
const node2 = new TreeNode(2, node7, node4);
const node6 = new TreeNode(6);
const node5 = new TreeNode(5, node6, node2);
const node0 = new TreeNode(0);
const node8 = new TreeNode(8);
const node1 = new TreeNode(1, node0, node8);
const root = new TreeNode(3, node5, node1);
const lca = lowestCommonAncestor(root, node5, node1);
console.log(lca ? lca.val : 'null');if (root === null) return null;
stop if reached empty subtree
if (root === p || root === q) return root; // found one target
return current node if it matches one target
const left = lowestCommonAncestor(root.left, p, q); // search left subtree
search left subtree recursively
const right = lowestCommonAncestor(root.right, p, q); // search right subtree
search right subtree recursively
if (left !== null && right !== null) return root; // targets found in both sides
if both sides found targets, current node is LCA
return left !== null ? left : right; // return non-null child or null
return whichever subtree found a target or null if none