前言
二叉搜索树,是按照中序遍历有序的二叉树。
给定两个节点,有三种情况。
1)分别在左右子树上,此时root满足要求(最近公共祖先)。也成为递归出口。
2)全部在左,那么将左节点作为根节点,继续根据1)来判断。
3)全部在右,那么将右节点作为根节点,继续根据2)来判断。
注:这是不断递归做事,而不是在回溯的时候才做事。
一、递归
按照上述思路进行不断递归。
//剑指offer68-I二叉搜索树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//一大一小,根据二叉搜索树的性质,它俩肯定在两边
if (root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left, p, q);
if (root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right, p, q);
return root;
}
二、循环
递归的本质为循环,区别在于递归压了函数栈,有回溯的时候。
但是本题不需要回溯,所以可转化为循环,将空间复杂度降了O(1)。
1、源码
public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
//一大一小,根据二叉搜索树的性质,它俩肯定在两边
while (root != null) {
if (root.val > p.val && root.val > q.val)
root = root.left;
else if (root.val < p.val && root.val < q.val)
root = root.right;
else
break;
}
return root;
}
总结
1)遇到二叉树必遍历,作为递归结构的二叉树,遍历需递归或循环+队列(DFS、BFS)。
2)递归能否转循环,看是否需要利用回溯过程。
3)利用已有条件来决定如何递归。