最近公共祖先 LCA

121 阅读1分钟

LeetCode 236

原题链接

代码如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 * 
 * LCA问题
 * 
 * 朝两个方向,一左一右,分别更新根节点,如果更新过程中
 * 遇到要找的节点p或q,则正在遍历的这个根节点是距离目标节点最近的一个根节点,直接返回
 * 但此时返回的根节点不一定符合公共祖先,因为无法确定要找的两个节点是否在同侧,有可能一左一右
 * 所以设置变量left, right 来记录从左和从右两个方向找到的目标祖先
 * 
 * Code by java
 */
class Solution {
	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
		// LCA 问题
		if (root == null) {
			return root;
		}
		if (root == p || root == q) {		//依次遍历整棵树,根节点移动的过程中,如果发现有根节点跟子节点相遇
			return root;					//则此时根节点可以作为最近祖先返回
		}
		TreeNode left = lowestCommonAncestor(root.left, p, q);		//一个方向向左,一个方向向右
		TreeNode right = lowestCommonAncestor(root.right, p, q);	//更换根节点,去找最近祖先
		if (left != null && right != null) {	//要找的两个目标节点,位于一左一右,所以左右都不为null,都找得到
			return root;						//所以返回root就是最近公共祖先
		} else if (left != null) {				//右边没找到,说明两目标节点都在左侧
			return left;						//所以返回左侧最深的祖先left即可
		} else if (right != null) {				//同理,两节点都在右侧,返回right即可		
			return right;
		}
		return null;							//遍历到头了,找不到目标节点,说明这一侧不存在祖先,因为两节点在右侧
	}
}