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.
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.
Solution:
  总结一下寻找最近公共祖先的题目吧:
  最暴力的方法,从上到下,遍历每个节点,对于每个节点的左右子树都判断一下【即向下遍历完其所有的子节点】,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】的更多相关文章

  1. PAT 甲级 1147 Heaps (30 分) (层序遍历,如何建树,后序输出,还有更简单的方法~)

    1147 Heaps (30 分)   In computer science, a heap is a specialized tree-based data structure that sati ...

  2. PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****

    1057 Stack (30 分)   Stack is one of the most fundamental data structures, which is based on the prin ...

  3. pat 甲级 1057 Stack(30) (树状数组+二分)

    1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the princi ...

  4. PAT甲级:1064 Complete Binary Search Tree (30分)

    PAT甲级:1064 Complete Binary Search Tree (30分) 题干 A Binary Search Tree (BST) is recursively defined as ...

  5. PAT甲级题解(慢慢刷中)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  6. PAT甲级1127. ZigZagging on a Tree

    PAT甲级1127. ZigZagging on a Tree 题意: 假设二叉树中的所有键都是不同的正整数.一个唯一的二叉树可以通过给定的一对后序和顺序遍历序列来确定.这是一个简单的标准程序,可以按 ...

  7. PAT甲级1119. Pre- and Post-order Traversals

    PAT甲级1119. Pre- and Post-order Traversals 题意: 假设二叉树中的所有键都是不同的正整数.一个唯一的二进制树可以通过给定的一对后序和顺序遍历序列来确定,也可以通 ...

  8. PAT甲级1057. Stack

    PAT甲级1057. Stack 题意: 堆栈是最基础的数据结构之一,它基于"先进先出"(LIFO)的原理.基本操作包括Push(将元素插入顶部位置)和Pop(删除顶部元素).现在 ...

  9. PAT甲级1026. Table Tennis

    PAT甲级1026. Table Tennis 题意: 乒乓球俱乐部有N张桌子供公众使用.表的编号从1到N.对于任何一对玩家,如果有一些表在到达时打开,它们将被分配给具有最小数字的可用表.如果所有的表 ...

随机推荐

  1. Springboot03-异常处理

    springboot默认异常处理 Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并然后返回一个固定的错误页面 统一异常处理 创建全局异常处理类 @ ...

  2. 微信小程序实战篇-分类页面制作

    https://blog.csdn.net/u012927188/article/details/73650264

  3. 不小心执行了 rm -f,先别急着跑路

    作者:justmine http://www.cnblogs.com/justmine/p/10359186.html 前言 每当我们在生产环境服务器上执行rm命令时,总是提心吊胆的,因为一不小心执行 ...

  4. 56.Decode String(解码字符串)

    Level:   Medium 题目描述: Given an encoded string, return it's decoded string. The encoding rule is: k[e ...

  5. tomcat在cmd中部署到系统服务

    基本步骤: 1.首先把整个tomcat拷贝到安装路径 2.打开cmd,设置JAVA_HOME,设置的值是对应cmd的局部变量 set JAVA_HOME=E:\tmp\2016\bghc\jdk1.7 ...

  6. oracle创建表空间自增空间管理

    表空间(tablespace).段(segment).区(extent).块(block),这些都是oracle数据库在数据文件中组织数据的基本单元 1.创建表空间create tablespace ...

  7. GitHub托管代码-学习笔记

    1.注册github账号 https://github.com/ 2.下载GitHub Desktop软件 https://desktop.github.com/ 在下载的软件上登陆GitHub账户 ...

  8. 2019牛客暑期多校训练营(第六场)C E H G

    C Palindrome Mouse E Androgynos 参考https://blog.csdn.net/birdmanqin/article/details/98479219这位大佬的.构造题 ...

  9. NOIP2016D1T3 换教室 (概率DP)

    NOIP2016D1T3 换教室 题目大意:有n个时间段,每个时间段i有两个教室a[i],b[i]可以上课,如果不申请换教室就在教室a[i]上课,如果换教室就在b[i]上课.你最多只能换m次教室.教室 ...

  10. Codeforces 1179D 树形DP 斜率优化

    题意:给你一颗树,你可以在树上添加一条边,问添加一条边之后的简单路径最多有多少条?简单路径是指路径中的点只没有重复. 思路:添加一条边之后,树变成了基环树.容易发现,以基环上的点为根的子树的点中的简单 ...