今天做了一个在线编程题,
题目是:求一个一般二叉树(非二叉搜索树)的最近公共祖先。
题目是:求一个一般二叉树(非二叉搜索树)的最近公共祖先。
题目要求不能使用额外空间来存储节点。
与二叉搜索树不同的是,每个叶子节点的数值value是没有规律的,
这就没有办法用什么乘2除2来做了。
解法的思路是:
* 从根节点开始遍历,如果node1和node2分别在root的左子树和右子树中,
* 那么根节点就是node1和node2的最近公祖先。
* 如果node1和node2都在左子树/右子树中,则递归左子树/右子树,
* 直到找到他们的最近公共节点。
/**
*
*/
package dianer;
/**
* @author LilyLee
* @date 2017年3月22日
* @time 下午5:08:43
* @Version 1.0
* @email lilylee_1213@foxmail.com
*
*/
/*
*
* 今天做了一个在线编程题,
* 题目是:求一个一般二叉树(非二叉搜索树)的最近公共祖先。
* 题目要求不能使用额外空间来存储节点。
*
* 解法思路:
* 从根节点开始遍历,如果node1和node2分别在root的左子树和右子树中,
* 那么根节点就是node1和node2的最近公祖先。
* 如果node1和node2都在左子树/右子树中,则递归左子树/右子树,
* 直到找到他们的最近公共节点。
*
*
*
* */
public class TreeLCA {
public static void main(String[] args) {
TreeLCA t = new TreeLCA();
t.test();
}
public class Node{
public int data;
public Node left;
public Node right;
Node(){}
Node(int data){this.data = data;}
}
public Node findLCA(Node root, Node n1, Node n2) {
if( root == null) //没找到
return null;
if(root.data == n1.data || root.data == n2.data) //找到
return root;
Node L = findLCA(root.left, n1, n2); //在左子树找
Node R = findLCA(root.right, n1, n2); //在右子树找
//当前结点左右子树都找到了n1和n2,那么这个结点就是LCA结点
if( L != null && R != null) {
return root;
}else {
return L != null ? L : R;
}
/*
if(L!=null){
if(R!=null){
return root;
}else return L;
}
else {
if(L!=null){
return root;
}else return R;
}
*/
}
//测试
public void test(){
Node[] A = new Node[20];
for(int i = 1; i < 20; i++) {
A[i] = new Node(i);
}
for (int i = 1; i < 8; ++i) {
A[i].left = A[i * 2 ];
A[i].right = A[i * 2 + 1];
}
/* 1
* 2 3
* 4 5 6 7
* 8 9 10 11 12 13 14 15
*
*/
Node ancestor = findLCA(A[1], A[12], A[11]);
if(ancestor==null) System.out.println("Not exist!");
else System.out.println("最近公共父节点为:"+ancestor.data);
}
}