笔试题回顾:通过前序遍历构建二叉树,然后查找最近公共祖先 Java

题目描述

在X星上有一类昆虫是可以进行无性繁殖的,身为昆虫调查员的你接到了命令前往X星去调查昆虫的繁殖情况。

经过一系列的调查,你发现该种昆虫一生最多可以繁殖出两个子代。现在你发现了这种昆虫身上可能会带有一种病毒,上级已经给你发来通知,告诉你两只带有病毒的昆虫编号。

为了快速找到这种病毒的来源,你必须找到这两只昆虫的最近公共祖先(不会存在两只昆虫出现相同编号)。

  • 输入描述
    单组输入。
    第1行包含一段序列,代表昆虫的序号。每个昆虫有两个子代,若没有子代则用-1代替。(如序列:1 2 -1 -1 3 -1 -1,表示1号昆虫有2、3两个子代而2、3没有子代,类似于二叉树的先序遍历) 。
    第2行,两个已知带有病毒的昆虫编号,用空格隔开。

  • 输出描述
    输出1行,表示两只病毒昆虫的最近公共祖先的编号。

  • 样例输入
    3 5 6 -1 -1 2 7 -1 -1 4 -1 -1 1 9 -1 -1 8 -1 -1
    5 1

  • 样例输出
    3

分析:本题目可以先将前序遍历转成二叉树,然后查找公共祖先


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] s = sc.nextLine().split(" ");
        int[] arr = Arrays.stream(s).mapToInt(Integer::parseInt).toArray();
        int a = sc.nextInt();
        int b = sc.nextInt();
        count = 0;
        Node root = createTree(arr);
        
        Node p = new Node(a);
        Node q = new Node(b);
        Node ancestor = findAncestor(root, p, q);
        
        System.out.println(ancestor.val);
    }

    /* 查找最近祖先*/
    public static Node findAncestor(Node root, Node p, Node q) {
        if (root == null || root.val == p.val || root.val == q.val) return root;
        Node Left = findAncestor(root.left, p, q);
        Node Right = findAncestor(root.right, p, q);
        if (Left == null) return Right;
        if (Right == null) return Left;
        return root;
    }

    static int count;

    /* 通过前序数组创建树 如:arr={ 1 2 -1 -1 3 -1 -1}*/
    public static Node createTree(int[] arr) {
        Node root = null;
        if (count < arr.length && arr[count++] != -1) {
            root = new Node(arr[count - 1]);
            root.left = createTree(arr);
            root.right = createTree(arr);
        }
        return root;
    }
}

/*
创建树的节点Node
 */
class Node {
    int val;
    Node left;
    Node right;

    public Node(int val) {
        this.val = val;
    }
}

PS:本人水平有限,文中如有错漏,欢迎大家指出。转载请注明来源。欢迎大家积极回复,学习的路上不想单机(︶︿︶)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值