剑指offer-第七章面试案例2(树中两个节点的公共祖先节点)
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack; //树中两个节点的最低公共祖先
//第一种情况:只是一颗二叉树,而且还是排序二叉树。思路:从根节点开始找起,如果这两个数一个大于
//根节点,一个小于根节点,那么最低公共子节点就是根节点。
//第二种情况:只是一颗普通的树,但是有指向父节点的指针。
//那么就变成 了两个链表求第一个公共节点的情况。
//第三种情况:只是一个普通的树,而且没有指针指向根节点。那么就只能用栈来存放遍历了的节点。找到相同的节点为止。
public class TreeLastCommonParent {
public class BiTreeNode{
int m_nValue;
BiTreeNode m_pLeft;
BiTreeNode m_pRight;
BiTreeNode m_pParent;
}
public BiTreeNode createBiTree(int[] pre,int start,int[] ord,int end,int length){
if(pre.length!=ord.length||pre==null||ord==null||length<=0)
return null;
int value=pre[start];
BiTreeNode root=new BiTreeNode();
root.m_nValue=value;
root.m_pRight=root.m_pLeft=null;
if(length==1){
if(pre[start]==ord[end])
return root;
else
throw new RuntimeException("inVaild put");
}
//遍历中序遍历的序列找到根节点
int i=0;
while(i<length){
if(ord[end-i]==value)
break;
i++;
}
int right=i;
int left=length-i-1;
if(left>0)
root.m_pLeft=createBiTree(pre,start+1,ord,end-i-1,length-i-1);
if(right>0)
root.m_pRight=createBiTree(pre,start+length-i,ord,end,i);
return root;
}
//该树是二叉树,而且还是排序二叉树。
public BiTreeNode commonParent1(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){
if(pHead==null)
return null;
if(p1.m_nValue<pHead.m_nValue&&p2.m_nValue>pHead.m_nValue
||p2.m_nValue<pHead.m_nValue&&p1.m_nValue>pHead.m_nValue){
return pHead; }
else if(p1.m_nValue<pHead.m_nValue&&p2.m_nValue<pHead.m_nValue){
return commonParent1(pHead.m_pLeft,p1,p2); }
else
return commonParent1(pHead.m_pRight,p1,p2);
}
//该树有指向父节点的指针
public BiTreeNode commonParent2(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){
if(pHead==null)
return null;
int len1=0;
int len2=0;
while(p1!=pHead){
len1++;
p1=p1.m_pParent;
}
while(p2!=pHead){
len2++;
p2=p2.m_pParent;
}
int dif=len1-len2;
BiTreeNode longest=p1;
BiTreeNode shortest=p2;
if(dif<0){
dif=len2-len1;
longest=p2;
shortest=p1;
}
for(int i=0;i<dif;i++)
longest=longest.m_pParent;
while(longest!=shortest){
longest=longest.m_pParent;
shortest=shortest.m_pParent;
}
return longest;
}
//该树没有指向父节点的指针
public BiTreeNode commonParent3(BiTreeNode pHead,BiTreeNode p1,BiTreeNode p2){ if(pHead==null)
return null;
Queue<BiTreeNode> path1=new LinkedList<BiTreeNode>();
Queue<BiTreeNode> path2=new LinkedList<BiTreeNode>();
Queue<BiTreeNode> longPath=path1;
Queue<BiTreeNode> shortPath=path2;
BiTreeNode head=pHead;
getNodePath(pHead,p1,path1);
pHead=head;
getNodePath(pHead,p2,path2);
int dif=path1.size()-path2.size(); if(dif<0){
dif=path2.size()-path1.size();
longPath=path2;
shortPath=path1;
}
for(int i=0;i<dif;i++){
longPath.remove();
}
while(longPath.peek()!=shortPath.peek())
{
longPath.remove();
shortPath.remove();
} return longPath.peek(); } public boolean getNodePath(BiTreeNode pHead,BiTreeNode p,Queue<BiTreeNode> path1){
if(pHead==null)
return false; if(pHead==p||getNodePath(pHead.m_pLeft,p,path1)||
getNodePath(pHead.m_pRight,p,path1)){
path1.add(pHead);
return true;
}
return false; } public static void main(String[] args){
int[] pre={8,4,3,7,9};
int[] ord={3,4,7,8,9};
TreeLastCommonParent treeLastCommon=new TreeLastCommonParent();
BiTreeNode pHead=treeLastCommon.createBiTree(pre,0,ord,pre.length-1,pre.length);
BiTreeNode p1=pHead.m_pLeft.m_pRight;
BiTreeNode p2=pHead.m_pLeft.m_pLeft;
BiTreeNode pCommon=treeLastCommon.commonParent1(pHead, p1, p2);
BiTreeNode pCommon3= treeLastCommon.commonParent3(pHead, p1, p2);
System.out.println(pCommon.m_nValue+" ");
System.out.println(pCommon3.m_nValue+" ");
}
}
剑指offer-第七章面试案例2(树中两个节点的公共祖先节点)的更多相关文章
- 剑指offer第七章&第八章
剑指offer第七章&第八章 1.把字符串转换成整数 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一个合法的数值则返回0 输入描述: 输入一个字符串 ...
- 剑指Offer(第二版)面试案例:树中两个节点的最低公共祖先节点
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/74612786冷血之心的博客) 剑指Offer(第二版)面试案例:树 ...
- 剑指offer第六章
剑指offer第六章 1.数字在排序数组中出现的次数 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在数组中出现了4次,所以输出4 分析:思路1 ...
- 剑指offer第五章
剑指offer第五章 1.数组中出现次数超过一半的数 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组 ...
- 剑指offer第四章
剑指offer第四章 1.二叉树的镜像 二叉树的镜像:输入一个二叉树,输出它的镜像 分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点. 求镜像的过程:先前序遍历这棵树的每个结点,如 ...
- 剑指offer第三章
剑指offer第三章 1.数值的整数次方 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. class Solution { public ...
- LeetCode题解汇总(包括剑指Offer和程序员面试金典,持续更新)
LeetCode题解汇总(持续更新,并将逐步迁移到本博客列表中) LeetCode题解分类汇总(包括剑指Offer和程序员面试金典) 剑指Offer 序号 题目 难度 03 数组中重复的数字 简单 0 ...
- 剑指Offer - 九度1352 - 和为S的两个数字
剑指Offer - 九度1352 - 和为S的两个数字2014-02-05 18:15 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于 ...
- 《剑指Offer》第二章(一)题3-8
为春招实习做准备,记录一下<剑指Offer>里面的面试题 第二章 面试题3:数组之中的重复数字. 这个题吧,虽然不难,但是不知道为什么就是看了很久,可能很久没有做算法题了.最后面一句话说的 ...
- LeetCode题解分类汇总(包括剑指Offer和程序员面试金典,持续更新)
LeetCode题解汇总(持续更新,并将逐步迁移到本博客列表中) 剑指Offer 数据结构 链表 序号 题目 难度 06 从尾到头打印链表 简单 18 删除链表的节点 简单 22 链表中倒数第k个节点 ...
随机推荐
- javascript 的dateObj.getTime() 在为C#的获取方式
public string GetTime(DateTime dt) { Int64 retval = 0; DateTime st = new DateTime(1970, 1, 1); TimeS ...
- Spark机器学习5·回归模型(pyspark)
分类模型的预测目标是:类别编号 回归模型的预测目标是:实数变量 回归模型种类 线性模型 最小二乘回归模型 应用L2正则化时--岭回归(ridge regression) 应用L1正则化时--LASSO ...
- 运行报警告UserWarning: Unknown extension is not supported and will be removed warn(msg)
运行python代码,出现如下警告: C:\Users\niko\PycharmProjects\python_new\venv\lib\site-packages\openpyxl\reader\w ...
- Apache 错误整理
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localho ...
- 如何修改Django中的日期和时间格式 DateTimeField
html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,比如数据库字段内容为2017-06-03 13:00:00,但是页面显示的却是Apr. 03, 2 ...
- undefined symbol: PyUnicodeUCS4_AsUTF8String
python 默认是ucs2编码进行编译,重新编译使用ucs4. python: ./configure --enable-unicode=ucs4 make && ...
- Qt开发串口
首先,在工程文件里面, QT += serialport 在头文件里面, #include <QSerialPort> 1.配置打开串口 QSerialPort* myserial = n ...
- Ctrl+Z 暂停程序及重启程序【转】
本文转自:https://blog.csdn.net/duyiwuer2009/article/details/43191799 Ctrl+Z - 暂停进程并放入后台 jobs - 显示当前暂停的进程 ...
- grep 使用场景
(1)结合find命令和管道 你的一个音乐文件夹里有多种格式的文件,而你只想找到艺术家jay的mp3文件,并且不含有任何的混合音轨 find . -name "*mp3" | ...
- Spring注解(赋值相关)
上面是与生命周期有关的内容,下面是属性赋值相关的: @Configuration public class ProperTyValueConfig { @Bean public Person pers ...