【剑指offer】 面试题50: 树中两个结点的最低公共祖先
2015-06-09 20:34
726 查看
题目描述:
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
存在, 2
不存在
方法一:
后序遍历
基本思想:
1、两个节点不在一条线上(即两个节点不存在一个节点是另一个节点的祖先的情况),则它们必定分别在所求节点A的左子树和右子树上,
后序遍历到第一个满足这个条件的节点就是所要求的节点A。
2、当这两个节点在一条线上,所求节点A则是这两个节点中深度最低的节点的父节点。
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 6 8
存在, 2
1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 6 12
不存在
方法一:
后序遍历
基本思想:
1、两个节点不在一条线上(即两个节点不存在一个节点是另一个节点的祖先的情况),则它们必定分别在所求节点A的左子树和右子树上,
后序遍历到第一个满足这个条件的节点就是所要求的节点A。
2、当这两个节点在一条线上,所求节点A则是这两个节点中深度最低的节点的父节点。
package com.offer.chapter_7; import java.util.Scanner; class BinaryTreeNode { public int elem; public BinaryTreeNode left; public BinaryTreeNode right; } /** * @author hadoop * * 求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor) * */ public class Interviews_50 { public static int curIndex = 0; public static BinaryTreeNode result = null; /** * * 构建二叉树 * */ public static void createBinaryTree(BinaryTreeNode curRoot, int[] data) { int leftElem = data[curIndex ++]; if(leftElem == 0) { curRoot.left = null; } else { BinaryTreeNode leftChild = new BinaryTreeNode(); leftChild.elem = leftElem; leftChild.left = leftChild.right = null; curRoot.left = leftChild; createBinaryTree(curRoot.left, data); } int rightElem = data[curIndex ++]; if(rightElem == 0) { curRoot.right = null; } else { BinaryTreeNode rightChild = new BinaryTreeNode(); rightChild.elem = rightElem; rightChild.left = rightChild.right = null; curRoot.right = rightChild; createBinaryTree(curRoot.right, data); } } /** * * 基本思想:如果这两个节点不在一条线上(即这两个节点不存在一个节点是另一个节点的祖先的情况),则它们必定分别在所求节点A的左子树和右子树上, * 后序遍历到第一个满足这个条件的节点就是所要求的节点A。否则,当这两个节点在一条线上,所求节点A则是这两个节点中深度最低的节点的父节点。 * * result 始终记录当前是否已经找到目标共同祖先结点 * */ public static int findLowestCommonAncestor(BinaryTreeNode curRoot, int a, int b, BinaryTreeNode parent) { int left = 0; int right = 0; // 判断左子树是否含有要判断的两节点之一 if(result == null && curRoot.left != null) { left = findLowestCommonAncestor(curRoot.left, a, b, curRoot); } // 判断右子树是否含有要判断的两节点之一 if(result == null && curRoot.right != null) { right = findLowestCommonAncestor(curRoot.right, a, b , curRoot); } // 判断当前结点是否是所查找结点之一 int mid = 0; if(curRoot.elem == a || curRoot.elem ==b) { mid = 1; } // 当前已经找到两个结点 if(result == null && (left + right + mid) == 2) { // 如果两个结点在一条路径上,则当前结点的父节点为共同祖先结点 if(mid == 1) { result = parent; } else { // 如果分别在当前结点的左右子树上,则当前结点为共同祖先结点 result = curRoot; } } // 返回当前子树中包含查找结点的个数 return (left + right + mid) > 0 ? 1 : 0; } /** * 二叉树中任意两个节点的最近公共祖先 */ public static void LowestCommonAncestor(BinaryTreeNode root, int a, int b) { result = null; if(root == null) { return; } findLowestCommonAncestor(root, a, b, null); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int num = scanner.nextInt(); while(num -- > 0) { BinaryTreeNode root = null; scanner.nextLine(); String string = scanner.nextLine(); String[] strs = string.split(" "); int[] data = new int[strs.length]; int a = scanner.nextInt(); int b = scanner.nextInt(); for(int i=0; i<strs.length; i++) { data[i] = Integer.parseInt(strs[i]); } if(data.length < 2) { System.out.println("My God"); } else { root = new BinaryTreeNode(); root.elem = data[0]; curIndex = 1; createBinaryTree(root, data); LowestCommonAncestor(root, a, b); if(result == null) { System.out.println("My God"); } else { System.out.println(result.elem); } } } } }
相关文章推荐
- 《剑指offer》面试题50 树中两个结点的最低公共祖先
- 案例二 树中两个结点的最低公共祖先
- 【剑指offer】 面试题50: 树中两个结点的最低公共祖先(二叉排序数)
- Java程序员的6个级别
- 网易面试题目
- php面试题整理
- 黑马程序员---集合-泛型、增强for、Set集合
- 程序员必读的职业规划书之摘要
- 黑马程序员---集合-Collection,List
- 黑马程序员——Foundation框架——包装类以及NSDate
- 推荐!国外程序员整理的Java资源大全
- 请不要说自己是 Java 程序员
- Google面试题-高楼扔鸡蛋问题
- 黑马程序员——Java基础---反射
- 黑马程序员——java基础(函数与数组)
- 悯码农 * 慧哥
- 请不要说自己是 Java 程序员
- 黑马程序员--代码块学习
- 黑马程序员+Java基础环境的搭建
- 黑马程序员——Foundation框架——NSArray和NSMutableArray