个人练习-PAT甲级-1143 Lowest Common Ancestor

题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805343727501312

题目大意:给出BST的先序遍历,给出两个节点,求这两个节点的最深公共祖先。如果节点不存在或者公共祖先不存在或某一个节点就是祖先,需要特殊输出。

思路:建树,DFS找出从根到UV的路径path_upath_v,然后遍历,找到第一个不相同的元素即可。没找到说明就是没有共同祖先。如果path_upath_v是空的,说明这个元素根本不在树里。

完整代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>


using namespace std;


class Node{
public:
    int val;
    Node* left, *right;

    Node(){left = right = nullptr;}
    Node(int val) { this->val = val; left = right = nullptr;}
};


vector<int> pre;
vector<int> path_u, path_v;
Node* root;


Node* buildTree(int s, int t) {
    if (s > t)
        return nullptr;
    Node* parent = new Node(pre[s]);
    int l = s+1;
    int r = l;
    while (r <= t) {
        if (pre[r] > pre[s])
            break;
        else
            r++;
    }
    parent->left = buildTree(l, r-1);
    parent->right = buildTree(r, t);
    return parent;
}


void getPath(vector<int>& path, Node* parent, int v) {
    if (parent == nullptr)
        return;
    path.push_back(parent->val);
    if (parent->val == v)
        return;
    if (v < parent->val)
        getPath(path, parent->left, v);
    else
        getPath(path, parent->right, v);
}


int main() {
    int M, N;
    scanf("%d %d", &M, &N);
    for (int i = 0; i < N; i++) {
        int tmp;
        scanf("%d", &tmp);
        pre.push_back(tmp);
    }

    root = buildTree(0, N-1);

    for (int i = 0; i < M; i++) {
        int U, V;
        bool flag_u = true, flag_v = true;
        scanf("%d %d", &U, &V);
        path_u.clear();
        path_v.clear();
        getPath(path_u, root, U);
        getPath(path_v, root, V);
        if (path_u.back() != U)
            flag_u = false;
        if (path_v.back() != V)
            flag_v = false;

        if (!flag_u & !flag_v) {
            printf("ERROR: %d and %d are not found.\n", U, V);
            continue;
        }
        if (!flag_u) {
            printf("ERROR: %d is not found.\n", U);
            continue;
        }
        if (!flag_v) {
            printf("ERROR: %d is not found.\n", V);
            continue;
        }

        int len = min(path_u.size(), path_v.size());
        int ptr;
        for (ptr = 0; ptr < len; ptr++) {
            if (path_v[ptr] != path_u[ptr])
                break;
        }
        ptr--;
        int A = path_v[ptr];
        if (U == A) {
            printf("%d is an ancestor of %d.\n", A, V);
            continue;
        }
        if (V == A) {
            printf("%d is an ancestor of %d.\n", A, U);
            continue;
        }
        printf("LCA of %d and %d is %d.\n", U, V, A);
    }

    delete root;

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值