LeetCode算法题(Go语言实现)_38

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

一、代码实现

go 复制代码
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
    }
    
    left := lowestCommonAncestor(root.Left, p, q)
    right := lowestCommonAncestor(root.Right, p, q)
    
    if left != nil && right != nil {
        return root
    }
    if left != nil {
        return left
    }
    return right
}

二、算法分析

1. 核心思路
  • 后序遍历:自底向上查找目标节点,通过递归返回值传递状态
  • 状态判断:当某个节点的左右子树分别包含目标节点时,即为LCA
2. 关键步骤
  1. 递归终止:遇到空节点或目标节点立即返回
  2. 子树搜索:分别在左右子树中查找目标节点
  3. 结果合并
    • 左右子树均有返回值 → 当前节点为LCA
    • 仅单侧有返回值 → 继续向上传递该结果
3. 复杂度
指标 说明
时间复杂度 O(n) 每个节点遍历一次
空间复杂度 O(h) 递归栈空间,h为树的高度

三、图解示例

四、边界条件与扩展

1. 特殊场景验证
  • 节点为根节点:返回根节点
  • 节点互为祖先:返回层级更高的节点
  • 节点不在树中:返回null(需预先验证)
2. 多语言实现
python 复制代码
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        return root if left and right else left or right
java 复制代码
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        return left != null && right != null ? root : left != null ? left : right;
    }
}

五、总结与扩展

1. 核心创新点
  • 状态传递:利用递归返回值携带子树搜索信息
  • 短路优化:发现目标节点后立即停止子树搜索
2. 扩展应用
  • 多节点LCA:扩展算法处理多个目标节点
  • 带父指针树:使用哈希表存储访问路径
  • 频繁查询优化:结合RMQ算法预处理
3. 工程优化
  • 迭代实现:用栈模拟后序遍历
  • 路径记录:显式存储节点访问路径
  • 输入验证:增加节点存在性检查
相关推荐
roman_日积跬步-终至千里几秒前
【Go语言基础【14】】defer与异常处理(panic、recover)
golang
Java 技术轻分享6 分钟前
《树数据结构解析:核心概念、类型特性、应用场景及选择策略》
数据结构·算法·二叉树··都差速
芜湖xin30 分钟前
【题解-洛谷】P1706 全排列问题
算法·dfs
孔令飞1 小时前
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
ai·云原生·容器·golang·kubernetes
chao_7891 小时前
链表题解——两两交换链表中的节点【LeetCode】
数据结构·python·leetcode·链表
曦月逸霜2 小时前
第34次CCF-CSP认证真题解析(目标300分做法)
数据结构·c++·算法
海的诗篇_3 小时前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法
自动驾驶小卡3 小时前
A*算法实现原理以及实现步骤(C++)
算法
Unpredictable2223 小时前
【VINS-Mono算法深度解析:边缘化策略、初始化与关键技术】
c++·笔记·算法·ubuntu·计算机视觉