PAT A1151 LCA in a Binary Tree

PAT A1151 LCA in a Binary Tree

((que1 <= idex && que2 >= idex) || (que1 >= idex && que2 <= idex))

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.
  • 思路 1:同A 1143!
    通过先序和中序找根,然后判断根是否是LCA:
    1- 如果u、v都在根的左边:递归的去左子树找
    2- 都在右边:递归去右子树找
    3- 其他情况有:
    -3-1:一边一个,此时的根就是u、v的LCA
    -3-2:一个是根:这个是另一个的LCA

  • TIPS :通过结点在中序序列的下标,就可以判断u、v是在根的做还是右->所以输入时应用一数组记录ino[]中结点对应的下标

  • code 1:

#include <iostream>
#include <unordered_map>
#include <vector> 
using namespace std;
const int maxn = 10100;	//!!!Wrong 1:结点数是10000,不是1000 
int n, m, q1, q2, que1, que2;
//int ino[maxn], preo[maxn];	//最好用vector,再resize设置大小,防止maxn写错
vector<int> ino, preo;
unordered_map<int, int> mark, pos;
void findRoot(int preL, int inL, int inR){
	if(inL > inR) return;
	int inRoot = pos[preo[preL]];
	int numL = inRoot - inL;
	if(que1 < inRoot && que2 < inRoot) //1- 都在左边 
		findRoot(preL+1, inL, inRoot-1);
	else if(que1 > inRoot && que2 > inRoot) //2- 都在右边 
		findRoot(preL+numL+1, inRoot+1, inR);
	else{	//3-
		if(que1 == inRoot || que2 == inRoot) //3-1 一个是根 
			printf("%d is an ancestor of %d.\n", que1 == inRoot? q1 : q2, que1 == inRoot? q2 : q1);
		else 	//3-2 一左一右:当前r为LCA 
			printf("LCA of %d and %d is %d.\n", q1, q2, ino[inRoot]);
		return;
	} 
}
int main(){
	scanf("%d %d", &m, &n);
	ino.resize(n+1); preo.resize(n+1);
	for(int i = 0; i < n; ++i){
		scanf("%d", &ino[i]);
		pos[ino[i]] = i; 
	}
	for(int i = 0; i < n; ++i){
		scanf("%d", &preo[i]);
		mark[preo[i]] = 1;
	}
	for(int i = 0; i < m; ++i){
		scanf("%d %d", &q1, &q2);
		que1 = pos[q1], que2 = pos[q2];
		if(mark[q1] * mark[q2] == 1) findRoot(0, 0, n-1);
		else if(mark[q1] == mark[q2]) printf("ERROR: %d and %d are not found.\n", q1, q2);	//都不是节点 
		else printf("ERROR: %d is not found.\n", mark[q1] == 0 ? q1 : q2);
	}
	return 0;
}
  • T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int in[maxn], pre[maxn];
unordered_map<int, int> pos;
bool flg;
void Create(int preL, int preR, int inL, int inR, int q1, int q2){
	if(preL > preR) return;
	int r = pre[preL], pos_r = pos[r];	//Wrong 1:样例4必超时 :用记录r在中序序列中的位置,来代替每次遍历
	int numL = pos_r - inL;
	if(flg){
		if(r == q1 || r == q2){
			printf("%d is an ancestor of %d.\n", r, r == q1 ? q2 : q1);
			flg = false;
		}else if(pos[q1] < pos_r && pos[q2] < pos_r){	//q1 q2 都在左子树 
			Create(preL + 1, preL + numL, inL, pos_r - 1, q1, q2);
		}else if(pos[q1] < pos_r || pos[q2] < pos_r){	//q1 q2 一左一右,GET! 
			printf("LCA of %d and %d is %d.\n", q1, q2, r);
			flg = false;
		}else{	//q1 q2 都在右子树 
			Create(preL + numL + 1, preR, pos_r + 1, inR, q1, q2); 
		}
	}
}
int main(){
	int nv, nq, tmp;
	scanf("%d %d", &nq, &nv);
	for(int i = 1; i <= nv; ++i){
		scanf("%d", &in[i]);
		pos[in[i]] = i;
	}
	for(int i = 1; i <= nv; ++i){
		scanf("%d", &pre[i]);	
	}
	for(int i = 0; i < nq; ++i){
		int q1, q2;
		scanf("%d %d", &q1, &q2);
		if(pos[q1] * pos[q2] > 0){
			flg = true;	// 剪枝,样例4 能省100ms 
			Create(1, nv, 1, nv, q1, q2);
		}else if(pos[q1] + pos[q2] > 0){
			printf("ERROR: %d is not found.\n", pos[q1] ? q2 : q1);
		}else{
			printf("ERROR: %d and %d are not found.\n", q1, q2);			
		}
	}
	return 0;
}
  • T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
vector<int> in, pre;
unordered_map<int, bool> mp;
unordered_map<int, int> in_ord;
bool flg;
void Create(int preL, int preR, int inL, int inR, int q1, int q2)
{
    if(preL >= preR || flg) return;
    int r = pre[preL];
    if(r == q1 || r == q2)
    {
        printf("%d is an ancestor of %d.\n", r , r == q1 ? q2 : q1);
        flg = true;
    }else if((in_ord[r] - in_ord[q1]) * (in_ord[r] - in_ord[q2]) < 0)
    {
        printf("LCA of %d and %d is %d.\n", q1, q2, r);
        flg = true;
    }
    int numL = in_ord[r] - inL, numR = inR - in_ord[r] - 1;
    if(numL > 0)
        Create(preL+1, preL+1+numL, inL, in_ord[r], q1, q2);
    if(numR > 0)
        Create(preL+1+numL, preR, in_ord[r]+1, inR, q1, q2);
}
int main()
{
    int nq, n;
    scanf("%d %d", &nq, &n);
    in.resize(n); pre.resize(n);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &in[i]);
        mp[in[i]] = true;
        in_ord[in[i]] = i;
    }
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &pre[i]);
    }
    for(int i = 0; i < nq; ++i)
    {
        int q1, q2;
        scanf("%d %d", &q1, &q2);
        if(mp[q1] & mp[q2] == true)
        {
            flg = false;
            Create(0, n, 0, n, q1, q2);
        }else if(mp[q1] || mp[q2])
        {
            printf("ERROR: %d is not found.\n", mp[q1] ? q2 : q1);
        }else
        {
            printf("ERROR: %d and %d are not found.\n", q1, q2);
        }
    }
    return 0;
}

  • T4 code:
#include <bits/stdc++.h>
using namespace std;
vector<int> pre, in;
unordered_map<int, int> pos_in;
unordered_map<int, bool> has;

void Create(int preL, int preR, int inL, int inR, bool & flg, int q1, int q2)
{
    if(preL >= preR || flg) return;
    int r = pre[preL], id = pos_in[r], numL = id - inL, pos1 = pos_in[q1], pos2 = pos_in[q2];
    int upper = max(pos1, pos2), lower = min(pos1, pos2);
    if(id == pos1 || id == pos2)
    {
        if(id == pos2) swap(q1, q2);
        printf("%d is an ancestor of %d.\n", q1, q2);
        flg = true;
    }else if(lower < id && id < upper)
    {
        printf("LCA of %d and %d is %d.\n", q1, q2, r);
        flg = true;
    }
    Create(preL+1, preL+1+numL, inL, inL+numL, flg, q1, q2);
    Create(preL+1+numL, preR, inL+numL+1, inR, flg, q1, q2);
}
int main()
{
    int nq, n;
    scanf("%d %d", &nq, &n);
    in.resize(n); pre.resize(n);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &in[i]);
        pos_in[in[i]] = i;
        has[in[i]] = true;
    }
    for(int i = 0; i < n; ++i) scanf("%d", &pre[i]);
    for(int i = 0; i < nq; ++i)
    {
        int q1, q2;
        scanf("%d %d", &q1, &q2);
        if(has[q1] && has[q2])
        {
            bool flg = false;
            Create(0, n, 0, n, flg, q1, q2);
        }else if(has[q1] || has[q2])
        {
            printf("ERROR: %d is not found.\n", has[q1] ? q2 : q1);
        }else
        {
            printf("ERROR: %d and %d are not found.\n", q1, q2);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值