235题-题目要求
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
现在有一棵搜索二叉树,这个二叉树的特点是左子树的节点一定小于根节点,而右子树的节点一定大于根节点。现在提供这棵树的根节点,并且输入两个节点,问这两个节点的最低共同父节点是谁?
最低共同父节点是指两个节点在沿父节点向上爬升时遇到的第一个共同父节点,同时它也允许父节点就是其本身,比如在上图中2和4的最低共同父节点就是2
思路和代码
这里我们因为可以根据数值来判断,需要寻找最低共同父节点的两个节点跟当前的根节点的大小比较,如果两个值都比根节点小,则最小父节点一定在左子树,二者都比它大,就在右子树。否则当前的根节点就是他们的最低共同父节点。
代码如下:这里采用递归的方式来寻找
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(p.val > q.val){
return lca(root, q, p);
}else{
return lca(root, p, q);
}
}
public TreeNode lca(TreeNode root, TreeNode small, TreeNode large){
if(root.val < small.val){
return lca(root.right, small, large);
}else if(root.val > large.val){
return lca(root.left, small, large);
}
return root;
}
236题 将搜索树改变为一般的二叉树
236题相对于235题而言,就是将题目中的搜索树条件改变成了一般的二叉树。这时我们无法通过和根节点比较数值大小来判断最低共同父节点究竟是在左子树还是右子树还是就是当前的根节点。
这时我们先试着用穷举法来找到所有可能的情况,现在已知根节点root和两个需要查找父节点的节点p,q
- p, q分别位于root的左子树和右子树: root为最低共同父节点
- p, q均位于root的左子树: 继续在root.left寻找最低共同父节点
- p, q均为与root的右子树: 继续在root.right寻找最低共同父节点
- root==p:最低共同父节点为p或p的某个父节点
- root==q:最低共同父节点为q或q的某个父节点
我们再进行汇总,如果我们在向下遍历左子树和右子树的过程中,一旦遇到p或q,则返回p或q,因为继续往下遍历的值都不会是p和q的共同父节点。如果左右子树返回的最低共同父节点值都不是空,说明p和q分别位于root的左右子树,那么root就是最低共同父节点。如果两个都为空,说明当前根节点不包含p和q。如果其中一棵子树返回的值不为空,那么就说明p和q都位于那棵子树上,且返回的值就是遍历过程中最先遇到的p或者q,也就是最低共同父节点。
代码如下:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null || root==p || root==q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right,p, q);
if(left!=null && right!=null) return root;
return left==null ? right : left;
}
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。