1.题目描述:
给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:对于有根树T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。
2.递归:
与leetcode236. 二叉树的最近公共祖先不同,二叉搜索树的特性决定了最近公共祖先的大小必在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) {
if (root == null || root.val >= Math.min(p.val, q.val) && root.val <= Math.max(p.val, q.val)) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
if (left != null) return left;//一旦找到必须返回,否则root会重复赋值,下同
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (right != null) return right;
return null;//实际不会走到这里
}
}
二刷:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root.val <= Math.max(p.val, q.val) && root.val >= Math.min(p.val, q.val)) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p ,q);
if (left != null) return left;
return right;
}
}
最优解:代码逻辑其实也是从上到下从父节点开始找。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > Math.max(p.val, q.val)) return lowestCommonAncestor(root.left, p, q);
if (root.val < Math.min(p.val, q.val)) return lowestCommonAncestor(root.right, p, q);
return root;
}
}
3.使用栈的迭代前序遍历:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return root;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode temp = stack.pop();
if (temp == null) continue;
if (temp.val >= Math.min(p.val, q.val) && temp.val <= Math.max(p.val, q.val)) return temp;
stack.push(temp.right);
stack.push(temp.left);
}
return null;
}
}
4.基于二叉搜索树特性的简化迭代遍历:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return root;
TreeNode temp = root;
while (true) {
if (temp.val > Math.max(p.val, q.val)) temp = temp.left;
else if (temp.val < Math.min(p.val, q.val)) temp = temp.right;
else return temp;
}
}
}