Leetcode235.二叉搜索树的最近公共祖先
-
思路分析
-
第一种解决方式,根据二叉树的最近公共祖先的思路,进行后序遍历,将结果返回到root,如果结果左节点中有相应的节点,则返回左节点,如果右节点中有相应的节点,则返回右节点,如果root节点中含有所需的所有节点,则返回该节点。
-
第二种解决思路
-
利用二叉搜索树的有序性,如果节点为最近公共节点的话,那么该节点一定在q和p为范围的区间之中,看图即可得知
5一定是在[1 ~ 9]的范围之中,但是3,8,6也在[1 ~ 9]范围之中,那么如何去筛选呢
-
筛选哪个是根节点的思路
根据图中显示,我们可以观察出,5是第一次进入[1 ~ 9]的范围之中的值,所以我们只要得到第一次进入该区间的值即可
-
-
递归三部曲
-
确定传入参数,传入根节点,需要确定的p和q节点,返回TreeNode节点
public TreeNode traversal(TreeNode root,TreeNode p,TreeNode q){ }
-
确定结束条件,如果cur的值为null,则返回cur即可
if(cur == null){return cur;}
-
确定单层递归逻辑
if(cur>q.var || cur>p.var ){ TreeNode left = traversal(cur.left,p,q); if(left !=null){ return left; } } if(cur<q.var || cur<p.var ){ TreeNode right = traversal(cur.right,p,q); if(right !=null){ return right; } } return cur;
-
关于二叉树使用单边遍历还是整棵树遍历的总结
-
单边遍历与整棵树遍历的区别
单边遍历
if(递归函数(cur.left)) return; if(递归函数(cur.right)) return;
整棵树遍历
TreeNode left = 递归函数(cur.left); TreeNode right = 递归函数(cur.right); 处理left与right的逻辑
-
关于单边遍历和整棵树遍历的区别
单边遍历时:如果遇到了符合条件的某个边,直接返回并结束递归,不会再去遍历另一条边
整棵树遍历时:即使某一条边上有符合条件的值,也需要再次遍历另一条边,并返回另一条边的数据
原因(以二叉树与二叉搜索树的最近公共祖先为例子)
-
由于二叉树是无序的,我们无法通过仅仅遍历一个边就能得到是否有公共祖先,所以我们采取的措施只能是回溯算法,将左右节点的结果返回给父节点,根据父节点的处理来判断是否是公共节点
二叉搜索树是有序的,并根据本题的分析,我们可以得知解题技巧,即只要有一个节点的值在[1~9]之间,我们就能返回确定该节点一定是最近公共节点,返回即可,因此不再需要遍历右子树,所以使用单边搜索会更好
总结
如果在回溯算法中,或者后序遍历中,我们大部分时间是需要使用left和right存取数值并交给根节点进行处理的
但是在面对一些已经知道具体顺序的树中,或者是前序遍历中,我们仅仅是进行查找数据,那么可以去使用单边遍历进行递归
-