[leetCode]剑指 Offer 68 - II. 二叉树的最近公共祖先
解法
从根节点开始,判断p,q是否存在于当前节点的左子树和右子树之中:
- 如果存在则当前节点为pq的最近公共节点
- 如果p q 在当前节点的左子树则遍历左子树
- 如果p q 在当前节点的右子树则遍历右子树
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null)
return null;
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)
return root;
else if (left != null)
return left;
else if (right != null)
return right;
return null;
}
}
解法二
使用前序遍历将p, q节点所在的路径保存下来,再寻找两条路径上最后的公共节点
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
LinkedList<TreeNode> path1 = new LinkedList<>();
getNodePath(root, p, path1);
LinkedList<TreeNode> path2 = new LinkedList<>();
getNodePath(root, q, path2);
return getLastCommonNode(path1, path2);
}
private boolean getNodePath(TreeNode root, TreeNode node, LinkedList<TreeNode> path) {
if (root == node) {
path.offer(root);
return true;
}
if (root == null)
return false;
path.offer(root);
boolean left = getNodePath(root.left, node, path);
if (left) return true;
boolean right = getNodePath(root.right, node, path);
if (right) return true;
path.pollLast();
return false;
}
private TreeNode getLastCommonNode
(
LinkedList<TreeNode> path1,
LinkedList<TreeNode> path2
) {
TreeNode last = null;
while (!path1.isEmpty() && !path2.isEmpty()) {
TreeNode node1 = path1.pollFirst();
TreeNode node2 = path2.pollFirst();
if (node1 == node2)
last = node1;
}
return last;
}
}