【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先

来源:互联网 发布:好看的美国电影 知乎 编辑:程序博客网 时间:2024/05/01 12:46

【试题描述】

求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor)。

 

二叉查找树

如果该二叉树是二叉查找树,那么求解LCA十分简单。

基本思想为:从树根开始,该节点的值为t,如果t大于t1和t2,说明t1和t2都位于t的左侧,所以它们的共同祖先必定在t的左子树中,从t.left开始搜索;如果t小于t1和t2,说明t1和t2都位于t的右侧,那么从t.right开始搜索;如果t1<t< t2,说明t1和t2位于t的两侧,那么该节点t为公共祖先。

如果t1是t2的祖先,那么应该返回t1的父节点;同理,如果t2是t1的祖先,应该返回t2的父节点。

【参考代码】

 1 public int query(Node t1, Node t2, Node t) { 2     int left = t1.value; 3     int right = t2.value; 4     Node parent = null; 5          6     if (left > right) { 7         int temp = left; 8         left = right; 9         right = temp;10     }11         12     while (true) {13         if (t.value < left) {14             parent = t;15             t = t.right;16         } else if (t.value > right) {17             parent = t;18             t = t.left;19         } else if (t.value == left || t.value == right) {20             return parent.value;21         } else {22             return t.value;23         }24     }25 }

 

普通二叉树

算法思想:如果一个节点的左子树包含p,q中的一个节点,右子树包含另一个,则这个节点就是p,q的最近公共祖先

【参考代码】

解法一:

 1 public static Node findNCA(Node root, Node p, Node q) 2     { 3         if (isintree(root.left, p) && isintree(root.left, q)) 4             return findNCA(root.left, p, q); 5         if (isintree(root.right, p) && isintree(root.right, q)) 6             return findNCA(root.right, p, q); 7         return root; 8     } 9 10     public static boolean isintree(Node root, Node node)11     {12         if (root == null)13             return false;14         if (root == node)15             return true;16         return isintree(root.left, node) || isintree(root.right, node);17     }

 

解法二:

 1 static int TWO_NODES_FOUND = 2; 2     static int ONE_NODES_FOUND = 1; 3     static int NO_NODES_FOUND = 0; 4  5     public static int covers(Node root, Node p, Node q) 6     { 7         int ret = NO_NODES_FOUND; 8         if (root == null) 9             return ret;10         if (root == p || root == q)11             ret += 1;12         ret += covers(root.left, p, q);13         if (ret == TWO_NODES_FOUND)14             return ret;15         return ret + covers(root.right, p, q);16     }17 18     private static Node findNCA(Node root, Node p, Node q)19     {20         if (q == p && (root.left == q || root.right == q))21             return root;22         int nodesFromLeft = covers(root.left, p, q);23         if (nodesFromLeft == TWO_NODES_FOUND)24         {25             if (root.left == p || root.left == q)26                 return root.left;27             else28                 return findNCA(root.left, p, q);29         } else if (nodesFromLeft == ONE_NODES_FOUND)30         {31             if (root == p)32                 return p;33             else if (root == q)34                 return q;35         }36 37         int nodesFromRight = covers(root.right, p, q);38         if (nodesFromRight == TWO_NODES_FOUND)39         {40             if (root.right == p || root.right == q)41                 return root.right;42             else43                 return findNCA(root.right, p, q);44         } else if (nodesFromRight == ONE_NODES_FOUND)45         {46             if (root == p)47                 return p;48             else if (root == q)49                 return q;50         }51 52         if (nodesFromLeft == ONE_NODES_FOUND53                 && nodesFromLeft == ONE_NODES_FOUND)54             return root;55         else56             return null;57     }

解法三:
网上版本:

 1 public static int FindNCA(Node root, Node a, Node b, Node out) 2     { 3         if (root == null) 4             return 0; 5         if (root == a || root == b) 6             return 1; 7  8         int iLeft = FindNCA(root.left, a, b, out); 9         if (iLeft == 2)10             return 2;11 12         int iRight = FindNCA(root.right, a, b, out);13         if (iRight == 2)14             return 2;15 16         if (iLeft + iRight == 2)17             out = root;18 19         return iLeft + iRight;20     }

这个网上说输出时 当为2时才输出,但是为2时,不能判断如果其中一个是另一个的父亲节点情况。所以理论上应该改为当返回结果
大于0时,就可以输出结果。但是不太确定正确性,应该程序是正确的。

 

参考:

http://blog.csdn.net/w397090770/article/details/7615447

 

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新房交房开发商拿不出证件怎么办? 新干式变压器未送电进水怎么办 三相380转单相220怎么办 外国人一直找你出去怎么办 美团众包跑腿单物品太重怎么办 美团退款成功后 物品怎么办 win10电脑没有网络图标怎么办 电脑开机桌面什么都没有怎么办 xp桌面什么都没有了怎么办 手机下滑通知栏不见了怎么办 跑800米赶上月经怎么办 强迫症吃药没效怎么办 复读生档案丢了怎么办 大学退学重新高考学籍怎么办 玻尿酸鼻子宽了怎么办 被昆山市圆通快递公司骗怎么办 借壳上市后壳公司怎么办 盐城国有民办学校倒闭教师怎么办 联想复印机显示更换墨粉盒怎么办 襄垣县共公自行车卡怎么办 转南京江宁户口怎么办儿童医保 剑与家园鬼服怎么办 花生苗出现虫洞怎么办 被蝎子草扎到手怎么办 被蝎子草蛰了怎么办 螫麻子草扎了怎么办 苹果app没删除干净怎么办 字写的太潦草看不懂怎么办 肝内胆管结石疼怎么办 肝内胆管有结石怎么办 肝里胆管有结石怎么办 被信任的人算计你怎么办 卡罗拉1.8油耗高怎么办 请问09年途锐柴油版怎么办 油电混合没电了怎么办 前向运动精子3%怎么办 精子活力正常精子活率低怎么办? 精子形态正常率低怎么办 前向运动精子20%怎么办 不运动精子率高怎么办 前向运动精子少怎么办