剑指–二叉搜索树的最近公共祖先
1,题目:
2,思路:
方法一:迭代:
根据以上定义,若 rootroot 是 p,qp,q 的 最近公共祖先 ,则只可能为以下情况之一:
- 1.p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
- 2.p=root,且 q 在 root的左或右子树中;
- 3.q=root,且 p 在 root 的左或右子树中;
方法一:迭代
- 1.循环搜索: 当节点 root为空时跳出;
- 2.当 p,q 都在 root 的 右子树 中,则遍历至 root.right ;
- 3.否则,当 p,q 都在 root 的 左子树 中,则遍历至 root.left ;
- 4.否则,说明找到了 最近公共祖先 ,跳出。
- 5.返回值: 最近公共祖先 root 。
下面是对应的图解:
方法二:递归:
递推工作:
1.当 p,q 都在 root 的 右子树 中,则开启递归 root.right 并返回;
2.否则,当p,q 都在 root 的 左子树 中,则开启递归 root.left 并返回;
3.返回值: 最近公共祖先 root 。
3,代码:
方法一:迭代:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
/*迭代:
根据以上定义,若 rootroot 是 p,qp,q 的 最近公共祖先 ,则只可能为以下情况之一:
1.p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
2.p=root,且 q 在 root的左或右子树中;
3.q=root,且 p 在 root 的左或右子树中;
方法一:迭代
1.循环搜索: 当节点 root为空时跳出;
2.当 p,q 都在 root 的 右子树 中,则遍历至 root.right ;
3.否则,当 p,q 都在 root 的 左子树 中,则遍历至 root.left ;
4.否则,说明找到了 最近公共祖先 ,跳出。
5.返回值: 最近公共祖先 root 。
*/
if(p.val > q.val) { // 保证 p.val < q.val
TreeNode tmp = p;
p = q;
q = tmp;
}
while(root != null) {
if(root.val < p.val) // p,q 都在 root 的右子树中
root = root.right; // 遍历至右子节点
else if(root.val > q.val) // p,q 都在 root 的左子树中
root = root.left; // 遍历至左子节点
else break;
}
return root;
}
}
方法二:递归:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//递归
/*
递推工作:
1.当 p,q 都在 root 的 右子树 中,则开启递归 root.right 并返回;
2.否则,当p,q 都在 root 的 左子树 中,则开启递归 root.left 并返回;
3.返回值: 最近公共祖先 root 。
*/
if(root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
if(root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
return root;
}
}