PAT甲级——A1151 LCA_in_a_BinaryTree【30】
The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U and V as descendants.
Given any two nodes in a binary tree, you are supposed to find their LCA.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers: M (≤ 1,000), the number of pairs of nodes to be tested; and N (≤ 10,000), the number of keys in the binary tree, respectively. In each of the following two lines, N distinct integers are given as the inorder and preorder traversal sequences of the binary tree, respectively. It is guaranteed that the binary tree can be uniquely determined by the input sequences. Then M lines follow, each contains a pair of integer keys U and V. All the keys are in the range of int.
Output Specification:
For each given pair of U and V, print in a line LCA of U and V is A. if the LCA is found and A is the key. But if A is one of U and V, print X is an ancestor of Y. where X is A and Y is the other node. If U or V is not found in the binary tree, print in a line ERROR: U is not found. or ERROR: V is not found. or ERROR: U and V are not found..
Sample Input:
6 8
7 2 3 4 6 5 1 8
5 3 7 2 6 4 8 1
2 6
8 1
7 9
12 -3
0 8
99 99
Sample Output:
LCA of 2 and 6 is 3.Solution:
8 is an ancestor of 1.
ERROR: 9 is not found.
ERROR: 12 and -3 are not found.
ERROR: 0 is not found.
ERROR: 99 and 99 are not found.
总结一下寻找最近公共祖先的题目吧:
最暴力的方法,从上到下,遍历每个节点,对于每个节点的左右子树都判断一下【即向下遍历完其所有的子节点】,a,b节点是否存在,若存在,则更新a,b节点的最近公共祖先即为该节点,从不通过不断向下更新公共祖先,那么最终得到的就是最近的公共祖先节点
当然,暴力法,我们不提倡,因为永远死在“运行超时”上
还有一种就是使用深度遍历,判断a,b是否在节点的左右两个子树上,从而得到最近公共祖先节点
另外一种就是先得到树的所有根节点【类似于重组树,但又不是真的重组】,然后根据节点a,b与每个根节点在中序遍历的位置【所以前提是要有中序遍历】,若,a,b在节点c的两边【包括节点c的位置】,那么c就是最近公共祖先节点 深度遍历方法:
使用leetcode第236题的答案讲解一下
一共有三种特殊情况,root == q 、root == p和root==null,这三种情况均直接返回root即可。
根据临界条件,实际上可以发现这道题已经被简化为查找以root为根结点的树上是否有p结点或者q结点,如果有就返回p结点或q结点,否则返回null。
这样一来其实就很简单了,从左右子树分别进行递归,即查找左右子树上是否有p结点或者q结点,就一共有4种情况:
第一种情况:左子树和右子树均找没有p结点或者q结点;(这里特别需要注意,虽然题目上说了p结点和q结点必定都存在,但是递归的时候必须把所有情况都考虑进去,因为题目给的条件是针对于整棵树,而递归会到局部,不一定都满足整体条件)
第二种情况:左子树上能找到,但是右子树上找不到,此时就应当直接返回左子树的查找结果;
第三种情况:右子树上能找到,但是左子树上找不到,此时就应当直接返回右子树的查找结果;
第四种情况:左右子树上均能找到,说明此时的p结点和q结点分居root结点两侧,此时就应当直接返回root结点了。
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==p||root==q||!root)return root;
TreeNode* left=lowestCommonAncestor(root->left, p, q);
TreeNode* right=lowestCommonAncestor(root->right, p, q);
if(!left&&!right)return NULL;
else if(left&&!right)return left;
else if(right&&!left)return right;
return root;
}
先得到根节点方法:
为本题答案。
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
int n, m;
vector<int>in, pre, root;
unordered_map<int, bool>map;
unordered_map<int, int>local;
void DFS(int inL, int inR, int preL, int preR)
{
if (inL > inR)return;
int k = inL;
while (k <= inR && in[k] != pre[preL])++k;
root.push_back(k);
int num = k - inL;
DFS(inL, k - , preL + , preL + num);
DFS(k + , inR, preL + num + , preR);
}
int main()
{
cin >> m >> n;
in.resize(n);
pre.resize(n);
for (int i = ; i < n; ++i)
{
cin >> in[i];
map[in[i]] = true;
local[in[i]] = i;
}
for (int i = ; i < n; ++i)
cin >> pre[i];
DFS(, n - , , n - );
while (m--)
{
int a, b;
cin >> a >> b;
if (!map[a] && !map[b])
printf("ERROR: %d and %d are not found.\n", a, b);
else if(!map[a])
printf("ERROR: %d is not found.\n", a);
else if(!map[b])
printf("ERROR: %d is not found.\n", b);
else
{
int res = ;
for (auto v : root)
{
if ((local[a] <= v && local[b] >= v) || (local[a] >= v && local[b] <= v))
{
res = in[v];
break;
}
}
if (res == a)
printf("%d is an ancestor of %d.\n", a, b);
else if (res == b)
printf("%d is an ancestor of %d.\n", b, a);
else
printf("LCA of %d and %d is %d.\n", a, b, res);
}
}
return ;
}
PAT甲级——A1151 LCA_in_a_BinaryTree【30】的更多相关文章
- PAT 甲级 1147 Heaps (30 分) (层序遍历,如何建树,后序输出,还有更简单的方法~)
1147 Heaps (30 分) In computer science, a heap is a specialized tree-based data structure that sati ...
- PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****
1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the prin ...
- pat 甲级 1057 Stack(30) (树状数组+二分)
1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the princi ...
- PAT甲级:1064 Complete Binary Search Tree (30分)
PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...
- PAT甲级题解(慢慢刷中)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- PAT甲级1127. ZigZagging on a Tree
PAT甲级1127. ZigZagging on a Tree 题意: 假设二叉树中的所有键都是不同的正整数.一个唯一的二叉树可以通过给定的一对后序和顺序遍历序列来确定.这是一个简单的标准程序,可以按 ...
- PAT甲级1119. Pre- and Post-order Traversals
PAT甲级1119. Pre- and Post-order Traversals 题意: 假设二叉树中的所有键都是不同的正整数.一个唯一的二进制树可以通过给定的一对后序和顺序遍历序列来确定,也可以通 ...
- PAT甲级1057. Stack
PAT甲级1057. Stack 题意: 堆栈是最基础的数据结构之一,它基于"先进先出"(LIFO)的原理.基本操作包括Push(将元素插入顶部位置)和Pop(删除顶部元素).现在 ...
- PAT甲级1026. Table Tennis
PAT甲级1026. Table Tennis 题意: 乒乓球俱乐部有N张桌子供公众使用.表的编号从1到N.对于任何一对玩家,如果有一些表在到达时打开,它们将被分配给具有最小数字的可用表.如果所有的表 ...
随机推荐
- Asp.Net Core 第06局:中间件
总目录 前言 本文介绍Asp.Net Core 中间件. 环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 开局 第一手:中间件概述 1.中间件:添加到应用 ...
- 【Oracle】详解v$session
首先查看一下v$session都存在哪些列 SYS@ORCL>desc v$session Name Null? ...
- Linux操作系统(三)_部署JDK
一.通过tar.gz压缩包安装 1.在usr目录下创建java目录 cd usr mkdir java 2.用rz命令上传tar.gz安装包到java目录 3.解压tar.gz安装包到当前目录 tar ...
- md5加密报错解决方法(TypeError: Unicode-objects must be encoded before hashing)
update()必须指定要加密的字符串的字符编码
- Jquery中input:type=radio的监听,获取设置值
一.html <div id='demo'> <input type='radio' name='sex' value='男' > <input type='radio' ...
- event代表事件的状态,专门负责对事件的处理,它的属性和方法能帮助我们完成很多和用户交互的操作;
IE的event和其他的标准DOM的Event是不一样的,不同的浏览器事件的冒泡机制也是有区别 IE:window.event.cancelBubble = true;//停止冒泡window.eve ...
- 初识Flink广播变量broadcast
Broadcast 广播变量:可以理解为是一个公共的共享变量,我们可以把一个dataset 或者不变的缓存对象(例如map list集合对象等)数据集广播出去,然后不同的任务在节点上都能够获取到,并在 ...
- [fw]GDT是在分段中為了相容real mode 跟 protected mode的產物
在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table). 为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型: 在R ...
- C#设计模式:观察者模式(Observer Pattern)
一,什么是观察者模式(Observer Pattern)? 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象 二,代码 ...
- 背包九讲(Orz)
P01: 01背包问题 题目 有\(N\)件物品和一个容量为\(V\)的背包.第\(i\)件物品的费用是\(c[i]\),价值是\(w[i]\).求解将哪些物品装入背包可使这些物品的费用总和不超过背包 ...