树中两个节点的最低公共祖先(Java实现)
2017-05-22 09:59
561 查看
本题为剑指offer面试题50
在牛客网没有找到类似的题目,所以笔者自己建了三棵树进行测试
如有问题欢迎指正。
题目:求树中两个结点的最低公共祖先
分析:其实这是一组题目,考官没有说清楚树的结构,那么做法就不尽相同。
比如,如果是二叉搜索树的话,我们只需从根结点判断,如果二结点与根的左右子树比较一大一小,那么跟结点就是二者最低公共祖先;如果二结点都比左子结点小,向左子树递归进行比较;如果二结点都比右子树结点大,向右子树递归进行比较;
如果不是二叉搜索树,但带有指向父节点的指针,那么此题转换成在两个有相交的链表上求第一个相交点。
如果不带指向父节点的指针,那么我们可以记录从根结点到这两个结点的路径即可求出。
以下代码是:普通树(多个子树),子树没有指向父节点的指针
Java代码如下:
在牛客网没有找到类似的题目,所以笔者自己建了三棵树进行测试
如有问题欢迎指正。
题目:求树中两个结点的最低公共祖先
分析:其实这是一组题目,考官没有说清楚树的结构,那么做法就不尽相同。
比如,如果是二叉搜索树的话,我们只需从根结点判断,如果二结点与根的左右子树比较一大一小,那么跟结点就是二者最低公共祖先;如果二结点都比左子结点小,向左子树递归进行比较;如果二结点都比右子树结点大,向右子树递归进行比较;
如果不是二叉搜索树,但带有指向父节点的指针,那么此题转换成在两个有相交的链表上求第一个相交点。
如果不带指向父节点的指针,那么我们可以记录从根结点到这两个结点的路径即可求出。
以下代码是:普通树(多个子树),子树没有指向父节点的指针
Java代码如下:
package go.jacob.day520; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javax.management.RuntimeErrorException; public class Demo1 { public static void main(String[] args) { test01(); System.out.println("=========="); test02(); System.out.println("=========="); test03(); } // 形状普通的树 // 1 // / \ // 2 3 // / \ // 4 5 // / \ / | \ // 6 7 8 9 10 public static void test01() { TreeNode n1 = new Tree d202 Node(1); TreeNode n2 = new TreeNode(2); TreeNode n3 = new TreeNode(3); TreeNode n4 = new TreeNode(4); TreeNode n5 = new TreeNode(5); TreeNode n6 = new TreeNode(6); TreeNode n7 = new TreeNode(7); TreeNode n8 = new TreeNode(8); TreeNode n9 = new TreeNode(9); TreeNode n10 = new TreeNode(10); n1.children.add(n2); n1.children.add(n3); n2.children.add(n4); n4.children.add(n6); n4.children.add(n7); n3.children.add(n5); n5.children.add(n8); n5.children.add(n9); n5.children.add(n10); System.out.println(getLastCommonParent(n1, n9, n10)); } // 树退化成一个链表 // 1 // / // 2 // / // 3 // / // 4 // / // 5 private static void test02() { TreeNode n1 = new TreeNode(1); TreeNode n2 = new TreeNode(2); TreeNode n3 = new TreeNode(3); TreeNode n4 = new TreeNode(4); TreeNode n5 = new TreeNode(5); n1.children.add(n2); n2.children.add(n3); n3.children.add(n4); n4.children.add(n5); System.out.println(getLastCommonParent(n1, n4, n5)); } // 树退化成一个链表,一个结点不在树中 // 1 // / // 2 // / // 3 // / // 4 // / // 5 private static void test03() { TreeNode n1 = new TreeNode(1); TreeNode n2 = new TreeNode(2); TreeNode n3 = new TreeNode(3); TreeNode n4 = new TreeNode(4); TreeNode n5 = new TreeNode(5); TreeNode n6 = new TreeNode(6); n1.children.add(n2); n2.children.add(n3); n3.children.add(n4); n4.children.add(n5); System.out.println(getLastCommonParent(n1, n5, n6)); } /* * 获取两个节点的最低公共祖先 */ public static TreeNode getLastCommonParent(TreeNode root, TreeNode p1, TreeNode p2) { //path1和path2分别存储根节点到p1和p2的路径(不包括p1和p2) List<TreeNode> path1 = new ArrayList<TreeNode>(); List<TreeNode> path2 = new ArrayList<TreeNode>(); List<TreeNode> tmpList = new ArrayList<TreeNode>(); getNodePath(root, p1, tmpList, path1); getNodePath(root, p2, tmpList, path2); //如果路径不存在,返回空 if (path1.size() == 0 || path2.size() == 0) return null; return getLastCommonParent(path1, path2); } // 获取根节点到目标节点的路径 public static void getNodePath(TreeNode root, TreeNode target, List<TreeNode> tmpList, List<TreeNode> path) { //鲁棒性 if (root == null || root == target) return; tmpList.add(root); List<TreeNode> children = root.children; for (TreeNode node : children) { if (node == target) { path.addAll(tmpList); break; } getNodePath(node, target, tmpList, path); } tmpList.remove(tmpList.size() - 1); } //将问题转化为求链表最后一个共同节点 private static TreeNode getLastCommonParent(List<TreeNode> p1, List<TreeNode> p2) { TreeNode tmpNode = null; for (int i = 0; i < p1.size(); i++) { if (p1.get(i) != p2.get(i)) break; tmpNode = p1.get(i); } return tmpNode; } // 节点类 private static class TreeNode { int val; List<TreeNode> children = new ArrayList<>(); public TreeNode(int val) { this.val = val; } @Override public String toString() { return val + ""; } } }
相关文章推荐
- 树中两个节点的最低公共祖先(Java实现)
- 二叉树两个节点求最近的公共祖先节点java代码实现
- 寻找二叉树两个节点的最低公共祖先
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 剑指offer——树中两个节点的最低公共祖先
- 二叉树中两个节点的最低公共祖先
- 剑指offer-树中两个节点的最低公共祖先
- 给定一棵二叉树。求两个树节点的最低公共祖先
- 剑指Offer:面试题50 树中两个节点的最低公共祖先
- 《剑指offer》编程题java实现(二十二):两个链表的第一个公共节点
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 求二叉树中两个节点p,q的最低公共祖先节点
- 一颗普通的二叉树,如何寻找两个节点的最低公共祖先(发现的一个与算法无关的引用问题)
- 二叉树(12)----查找两个节点最低祖先节点(或近期公共父节点等),递归和非递归
- 面试题50:树中两个节点的最低公共祖先
- 查找树中两个节点的最低公共祖先
- 求树中两个节点的最低公共祖先
- 二叉树系列——两个节点的最低公共祖先
- 【二叉树】寻找二叉树/BST的两个节点的最低公共祖先
- 面试题之树中两个节点的最低公共祖先节点