奇安信集团笔试题:二叉树的最近公共祖先(leetcode236),杀死进程(leetcode582)

Posted 一只猫的旅行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇安信集团笔试题:二叉树的最近公共祖先(leetcode236),杀死进程(leetcode582)相关的知识,希望对你有一定的参考价值。

1. 二叉树最近公共祖先

 
 
奇安信集团 2020校招 服务端开发-应用开发方向在线考试
编程题|20分2/2
寻祖问宗
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
姓氏是人的符号标志,是家族血脉的传承;族谱是家族血脉传承的文字记载。同姓的两个中国人,根据族谱或许能够查出上面几代内是同一个祖先。查一下族谱,也许当代某位同姓名人就是你的远房亲戚,惊喜不惊喜,意外不意外!!!

 

输入
二元查找树(1.若左子树不空,左子树值都小于父节点;2.如右子树不空,右子树值都大于父节点;3.左、右子树都是二元查找树;4. 没有键值相等的节点)上任意两个节点的值,请找出它们最近的公共祖先。

输入三行行,第一行为树层级,第二行为数节点(其中
-1表示为空节点),第三行为需要查找祖先的两个数。
在例图中(虚线框没有真实节点,为了输入方便对应位置输
-1)查找12和20的最近公共祖先输入为: 4 9 6 15 2 -1 12 25 -1 -1 -1 -1 -1 -1 20 37 12 20 输出 输出给出两个数在树上的最近公共祖先数值,如果没有公共祖先,输出-1;如果其中一个节点是另一个节点的祖先,输出这个祖先点(如例图中找15、20最近公共祖先,输出15);如果输入无效,输出-1。 样例输入 4 9 6 15 2 -1 12 25 -1 -1 -1 -1 -1 -1 20 37 12 20 样例输出 15

 

解题思路:

从根节点开始遍历树。
如果当前节点本身是 p 或 q 中的一个,我们会将变量 mid 标记为 true,并继续搜索左右分支中的另一个节点。
如果左分支或右分支中的任何一个返回 true,则表示在下面找到了两个节点中的一个。
如果在遍历的任何点上,左、右或中三个标志中的任意两个变为 true,这意味着我们找到了节点 p 和 q 的最近公共祖先。

作者:LeetCode
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/er-cha-shu-de-zui-jin-gong-gong-zu-xian-by-leetcod/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

代码,全A:

import java.util.LinkedList;
import java.util.Scanner;

public class Main{
    static class TreeNode{
        int value;
        TreeNode left;
        TreeNode right;
        public TreeNode(int value){
            this.value = value;
        }
    }
    public static TreeNode root;
    public static TreeNode p;
    public static TreeNode q;
    public static TreeNode commonfather;
    public static void main(String[] args) {
        
        /***********************层次创建二叉树***********************/
        Scanner sc = new Scanner(System.in);
        int depth = sc.nextInt();
        sc.nextLine();
        String[] array1 = sc.nextLine().trim().split(" ");
        int pval = sc.nextInt();
        int qval = sc.nextInt();
        int len = array1.length;
        int[] intlevelarray = new int[len];
        for (int i = 0; i < len; i++) {
            intlevelarray[i] = Integer.valueOf(array1[i]);
        }
        root = level_buildBTree(intlevelarray,-1,pval,qval);
        boolean result = recurseTree(root, p, q);
        if(result && commonfather!=null){
            System.out.println(commonfather.value);
        }else{
            System.out.println(-1);
        }
        
        
    }
    /**层次遍历创建二叉树*/
    public static TreeNode level_buildBTree(int[]array,int flag, int pval, int qval){
        int len = array.length;
        //将数组转成list
        LinkedList<TreeNode> list = new LinkedList<>();
        for (int i = 0; i < len; i++) {
            TreeNode temp = new TreeNode(array[i]);
            if(array[i]==pval){
                p = temp;
            }
            if(array[i]==qval){
                q = temp;
            }
            list.add(temp);
        }
        //开始构建树
        for (int i = 0; i < len/2; i++) {
            list.get(i).left = list.get(2*i+1).value!=flag?list.get(2*i+1):null;
            //记得处理最后一个父节点(len/2-1),因为有可能没有右孩子。
            if(i<len/2-1 ||(i==len/2-1&& len%2!=0)){
                list.get(i).right = list.get(2*i+2).value!=flag?list.get(2*i+2):null;
            }
        }
        return list.get(0);
    }
    
    /**
     * 二叉树的最近公共祖先
     * @param currNode 当前节点
     * @param p 第一个孩子
     * @param q    第二个孩子
     * @return
     */
    public static boolean recurseTree(TreeNode currNode, TreeNode p, TreeNode q){
        if(currNode == null){
            return false;
        }
        int left = recurseTree(currNode.left, p, q)?1:0;
        int right = recurseTree(currNode.right, p, q)?1:0;
        int mid = (currNode==p || currNode==q)?1:0;
        if(mid+left+right>=2){
            commonfather = currNode;
        }
        return mid+left+right>0;
    }
}

 

2. 杀死进程

题目描述:

奇安信集团 2020校招 服务端开发-应用开发方向在线考试
编程题 | 20.0分1/2
结束进程树
时间限制:C/C++语言 1000MS;其他语言 3000MS
内存限制:C/C++语言 65536KB;其他语言 589824KB
题目描述:
给定n个进程,这些进程满足以下条件:

(1)每个进程有唯一的PID,其中PID为进程ID

(2)每个进程最多只有一个父进程,但可能有多个子进程,用PPID表示父进程ID

(3)若一个进程没有父进程,则其PPID为0

(4)PID、PPID都是无符号整数

结束进程树的含义是当结束一个进程时,它的所有子进程也会被结束,包括子进程的子进程。


现在给定大小为n的两组输入列表A和B(1 <= n <= 100),列表A表示进程的PID列表,列表B表示列表A对应的父进程的列表,即PPID列表。

若再给定一个PID,请输出结束该PID的进程树时总共结束的进程数量。

输入
3 1 5 21 10

0 3 3 1 5

5

输出
2


样例输入
3 1 5 21 10
0 3 3 1 5
3

样例输出
5

 

解题思路:

https://www.cnblogs.com/yoke/p/9770528.html

 

代码,91%

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
 
public class Main3 {
    public static int[] pid ;
    public static int[] ppid ;
    public static void main( String[] args ) {
        Scanner sc = new Scanner(System.in);
        String[] a = sc.nextLine().trim().split(" ");
        String[] b = sc.nextLine().trim().split(" ");
        int kill = sc.nextInt();
        pid = new int[a.length];
        ppid = new int[b.length];
        for (int i = 0; i < a.length; i++) {
            pid[i]= Integer.valueOf(a[i]);
        }
        for (int i = 0; i < b.length; i++) {
            ppid[i]=Integer.valueOf(b[i]);
        }
        List<Integer> result = killpid(kill);
        if(result!=null){
           System.out.println(result.size()); 
        }else{
            System.out.println(0); 
        }
    }
    
    public static List<Integer> killpid(int kill){
        List<Integer> result = new ArrayList<Integer>();
        result.add(kill);
        for (int i = 0; i < ppid.length; i++) {
            if(ppid[i]==kill){
                result.addAll(killpid(pid[i]));
            }
        }
        return result;
    }
}

 

以上是关于奇安信集团笔试题:二叉树的最近公共祖先(leetcode236),杀死进程(leetcode582)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 236.二叉树的最近公共祖先

LeetCode二叉树的最近公共祖先

LeetCode 236. 二叉树的最近公共祖先

LeetCode 236. 二叉树的最近公共祖先

leetcode 236 二叉树的最近公共祖先

二叉树15:二叉树的最近公共祖先