【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
- 【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先
- 寻找二叉树两节点的最近的公共祖先
- 寻找二叉树两节点的最近的公共祖先[转载+整理]
- 寻找二叉树中两个节点的最近的公共祖先——迅雷笔试归来
- 微软亚洲工程院面试题:寻找两个二叉树节点的最近祖先
- 面试题50:求二叉树中两个节点的最近公共祖先
- 面试题07 - 二叉树两节点的最低公共祖先 [树]
- 二叉树问题——寻找二叉树中两个节点的最近公共祖先
- 寻找两个节点的最近公共祖先
- 寻找二叉树中两个节点的最近的公共祖先
- 寻找二叉树中两个节点的最近的公共祖先
- 【数据结构】二叉树中任意两节点的最近公共祖先节点
- 判断二叉树是不是完全二叉树/求两节点最近的公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点
- 寻找二叉树两个节点的最低公共祖先(LCA)
- 【CB Insights全球最强AI创新公司Top100榜单】旷视、商汤、寒武纪等7家中国公司入选
- 【IT笔试面试题整理】二叉树中和为某一值的路径--所有可能路径
- 【IT笔试面试题整理】字符串的排列
- 【IT笔试面试题整理】字符串的组合
- TCP/IP协议三次握手和四次挥手大白话解说
- 【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先
- 20171215Capstone培训班
- 【IT笔试面试题整理】反转链表
- 【IT笔试面试题整理】字符串转数组+数组转字符串
- 【IT笔试面试题整理】判断链表是否存在环路,并找出回路起点
- 【IT笔试面试题整理】判断一个二叉树是否是平衡的?
- 关于笔记本安装Deepin 或者ubuntu操作系统,无法进入界面。
- 【IT笔试面试题整理】删除无序链表中重复的节点
- 如何配置MySQL数据库超时设置