题目:最近公共祖先
思路1:
在某个节点小找是否包含某个子节点很容易,所以我们可以对所有节点,判断是否包含给定的两个节点,取最近的即可。这个方法可以AC,但其实,两个递归做了很多重复的运算。
思路2:
其实,祖先节点只有如下三种情况
- 两个节点分别在祖先节点两侧;
- a节点就是他们的祖先,b节点在a的左子树或右子树;
- b节点就是他们的祖先,a节点在b的左子树或右子树;
我们从头深搜二叉树,
- 如果
root
节点为空, 或者当前root
节点等于两个节点其中一个,就返回当前节点root
; - 递归对
root
左子树、root
右子树分别查找:
如果左右子树返回的结果都不为空,说明左右子树分别找到了两个节点,此时,root
即为所求,返回即可;(情况1)
否则,返回左右子树的返回结果不为空的节点。(情况2或3)
代码1:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int res;
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
search(root, o1, o2);
return res;
}
public void search (TreeNode root, int o1, int o2) {
if (root == null) {
return;
}
if (contains(root, o1) && contains(root, o2)) {
res = root.val;
}
search(root.left, o1, o2);
search(root.right, o1, o2);
}
public boolean contains (TreeNode root, int num) {
if (root == null) {
return false;
}
if (root.val == num) {
return true;
}
return contains(root.left, num) || contains(root.right, num);
}
}
代码2:
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @param o1 int整型
* @param o2 int整型
* @return int整型
*/
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
return search(root, o1, o2).val;
}
public TreeNode search (TreeNode root, int o1, int o2) {
if (root == null || root.val == o1 || root.val == o2) {
return root;
}
TreeNode left = search(root.left, o1, o2);
TreeNode right = search(root.right, o1, o2);
if (left != null && right != null) {
return root;
}
return left == null? right: left;
}
}