剑指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个节点 ...
随机推荐
- Sublime : python环境
1.安装python.注意区分32位和64位版本,勾选下图红框实现自动将python安装位置添加到环境变量 2.键盘win+r,输入cmd调出命令行,输入python回车,根据结果查看时候安装成功 3 ...
- 20145217《网络对抗》 MAL_简单后门学习总结
20145217<网络对抗> MAL_简单后门学习总结 实践内容: 1.netcat的应用 2.socat的应用 3.meterpreter的应用 知识点学习总结 后门程序一般是指那些绕过 ...
- 20145222黄亚奇《网络对抗》web安全基础实践
web安全基础实践 实验后回答问题 (1)SQL注入攻击原理,如何防御 原理:指web应用程序对用户输入数据的合法性没有判断,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语 ...
- Convolutional Neural Network
Why CNN for Image 图片是由像素点组成的,可以这样来解释深度神经网络对图片的处理. 第一层的layer是最基本的分类器,区分一些基本的特征,比如颜色.是否有斜线. 第二层的layer会 ...
- 编译lineageos
lineageos 2 -- 编译rom包 fu*k小米,手机老是1年左右出现充不进去电.前段时间我的红米note4x突然充不进去电了,只好新买了个手机(买手机先看lineageos支持列表 ^_^) ...
- 洛谷P3393逃离僵尸岛 最短路
貌似一直不写题解不太好QAQ 但是找不到题啊... 随便写点水题来补博客吧 题目不pa了,点链接吧... 点我看题 很明显这是道sb题... 思路: 对于每一个僵尸城市预处理其 s 距离内的城市,然 ...
- LuManager升级php5.6.27方法
LuManager自带的PHP在FastCGI模式是 5.2.17版,非FastCGI模式是 5.3.14版.由于360网盘的停服,已不敢再用那些免费的网盘,干脆自己搭个私有云.查了下相关资料准备先试 ...
- spark学习(RDD案例实战)
练习0(并行化创建RDD) 先启动spark-shell 通过并行化生成rdd scala> val rdd1 = sc.parallelize(List(63,45,89,23,144,777 ...
- UVA 1639 Candy (组合数+精度)
题意:两个箱子,每个箱子有n颗糖,每次有p的概率拿1号箱子的一颗糖出来(有1-p的概率拿2号箱子的一颗糖出来),问当打开某个箱子为空的时候,另一个箱子的期望糖的数量是多少 题解:枚举另一个箱子的糖的数 ...
- strcpy的实现
// // Strcpy.c // libin // // Created by 李宾 on 15/8/20. // Copyright (c) 2015年 李宾. All rights reserv ...