标签:
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
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).”
_______3______ / ___5__ ___1__ / \ / 6 _2 0 8 / 7 4
For example, the lowest common ancestor (LCA) of nodes 5
and
1
is 3
. Another example is LCA of nodes 5
and
4
is 5
, since a node can be a descendant of itself according to the LCA definition.
题意:给定一棵二叉树,查找两个节点的最接近的共同祖先LCA
分类:二叉树
解法1:要找到共同祖先,由于不是BST树,没有大小关系存在。但是我们可以想到后序遍历,对于后序遍历,是先遍历左子树,再右子树,最后是当前节点。
假设要找的是p,q两个节点的共同祖先,对于root节点,我们假设有一个函数
p,q都在左子树,那么应该在左子树找到p和q,而右子树则两者都找不到,这是我们可以判断共同祖先在左子树,递归查找。
如果p,q都在右子树,同样道理,左子树一个都找不到,那么我们递归在右子树里面找。
如果p,q在root的两侧,那么左子树和右子树都应该有返回值,这是root就是最近共同祖先。
并且这里有一个技巧,就是不必p,q都找到,例如在递归左子树的时候,先找到了p,我们就可以直接去右子树找,如果右子树没有找到q,意味着q在左子树
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == p || root == q || root == null) { return root; }//如果已经找到p,q返回,或者root为null,返回null TreeNode left = lowestCommonAncestor(root.left, p, q);//先在左子树找 TreeNode right = lowestCommonAncestor(root.right, p, q);//再找右子树 if(left != null && right != null){//如果左右子树分别有一个,则返回根节点 return root; }else if(left!=null){//如果只在左子树,返回left return left; }else{//如果只在右子树,返回right return right; } } }
解法2:同样是后序遍历,使用后序遍历非递归算法一边遍历一边存储路径,找到p,q并且把它们的路径分别存储起来
最后比较这两条路径,找到最后一个相同的节点,则为所求
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { Stack<TreeNode> stack = new Stack<TreeNode>(); ArrayList<TreeNode> path1 = new ArrayList<TreeNode>(); ArrayList<TreeNode> path2 = new ArrayList<TreeNode>(); int found = 0;//当前路径标志 TreeNode cur = root; do{ if(found==2) break; while(cur!=null){ stack.add(cur); cur = cur.left; } TreeNode t = null; boolean flag = false; while(stack.size()>0&&!flag){ cur = stack.peek(); if(cur.right==t){//如果这个节点右节点为null或者右节点已经访问过 if(cur==p||cur==q){//判断是不是p,q,如果是就保存当前路径 if(found==0) path1.addAll(stack); else path2.addAll(stack); found++; } stack.pop(); t = cur; }else{//如果右节点没有被访问过,先遍历右子树 flag = true; cur = cur.right; } } }while(stack.size()>0); int i = 0; while(i<path1.size()&&i<path2.size()){//从头开始查找最后一个相同的节点 if(path1.get(i)!=path2.get(i)) break; else i++; } return path1.get(i-1); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
leetcode--Lowest Common Ancestor of a Binary Tree
标签:
原文地址:http://blog.csdn.net/crazy__chen/article/details/47185439