剑指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个节点 ...
随机推荐
- Python中的WebSocket
一.Websockets介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...
- Http请求的TCP连接
我们一直认为,HTTP连接分为长连接和短连接,而我们现在常用的都是HTTP1.1,因此我们用的都是长连接. 这句话其实只对了一半,我们现如今的HTTP协议,大部分都是1.1的,因此我们平时用的基本上都 ...
- GPL协议本身就是剥削,oracle维权玩的让人恶心
我们先来看一下MySQL的版权问题.当前,MySQL采用双重授权(Dual Licensed),他们是GPL和MySQL AB制定的商业许可协议.如果你在一个遵循GPL的自由(开源)项目中使用MyS ...
- jQuery农历黄历日期表
在线演示 本地下载
- socket IPC(本地套接字 domain)
1.简介 socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通 ...
- Go语言学习之数据类型以及类型转换(The way to go)
生命不止,继续go go go 介绍来go中的变量和常量,今天介绍一下go中的基本类型. 可以分为四大类,现在一点点道来. Boolean Types 布尔类型,不用过多介绍来吧,就是true和fal ...
- matlab 学习笔记
脚本名称不能与matlab里面的关键字一样.否则会报当MATLAB中报错,“SCRIPT ******”怎么解决 保留已画图形:hold on 矩阵连接:横向 f=[m,n]; 纵向 f=[m;n ...
- spring mvc: 静态资源/文件配置
静态文件不用再放web-info 下面了,放在webapp/ 下面就行了(静态文件放web-inf下你在jsp都无法引用~ 注意一下所有js.css包括报表文件~ 配置文件等等等~ 不要放在web ...
- 三十五 Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy分布式爬虫要点
1.分布式爬虫原理 2.分布式爬虫优点 3.分布式爬虫需要解决的问题
- DDOS工具合集---CC 2.0(僵尸网络proxy,单一url,可设置cookie,refer),传奇克星(代理+单一url,可设置cookie),NetBot_Attacker网络僵尸1.0(僵尸网络,HTTP NO-Cache Get攻击模式,CC攻击,HTTP空GET请求攻击),傀儡僵尸VIP1.4版(僵尸网络,动态单一url)、上兴网络僵尸2.3、中国制造网络僵尸、安全基地网络僵尸==
DDOS工具合集 from:https://blog.csdn.net/chinafe/article/details/74928587 CC 著名的DDOS CC工具,效果非常好!CC 2.0使用了 ...