package main
import "fmt"
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil || root == p || root == q {
return root // base case: found p or q or reached leaf
}
left := lowestCommonAncestor(root.Left, p, q) // search left subtree
right := lowestCommonAncestor(root.Right, p, q) // search right subtree
if left != nil && right != nil {
return root // p and q found in different subtrees, root is LCA
}
if left != nil {
return left // p and q both in left subtree
}
return right // p and q both in right subtree or none found
}
func main() {
// Construct the tree
root := &TreeNode{Val: 3}
root.Left = &TreeNode{Val: 5}
root.Right = &TreeNode{Val: 1}
root.Left.Left = &TreeNode{Val: 6}
root.Left.Right = &TreeNode{Val: 2}
root.Left.Right.Left = &TreeNode{Val: 7}
root.Left.Right.Right = &TreeNode{Val: 4}
root.Right.Left = &TreeNode{Val: 0}
root.Right.Right = &TreeNode{Val: 8}
p := root.Left // node 5
q := root.Right // node 1
lca := lowestCommonAncestor(root, p, q)
fmt.Printf("Lowest Common Ancestor of %d and %d is %d\n", p.Val, q.Val, lca.Val)
}
if root == nil || root == p || root == q {
stop recursion if current node is null or matches p or q
left := lowestCommonAncestor(root.Left, p, q)
search left subtree for p or q
right := lowestCommonAncestor(root.Right, p, q)
search right subtree for p or q
if left != nil && right != nil {
if p and q found in different subtrees, current node is LCA
if both found in left subtree, return left
otherwise return right subtree result
Lowest Common Ancestor of 5 and 1 is 3