字节3-14笔试
字节3-14笔试第一题:
一串0101010…数组代表一个环形序列的位置状态,0空位1有人,某人找空位,尽量离有人的位置远一些,即找的一个空位置,该位置向前的距离和向后的距离的最小值可以表示该位置的“空位评估数”,找到环形序列里的最大的空位评估数
import java.util.*; //双向链表 class Node { int data; Node pre; Node next; Node(int data) { this.data = data; } } public class Main { public static void main(String[] args) { int[] arr = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; //int[] arr = {0, 1, 2, 3}; //创建位置状态双向循环链表 Node head = new Node(arr[0]); Node p = head; for (int i = 1; i < arr.length; i++) { Node cur = new Node(arr[i]); cur.pre = p;//注入前置节点 p.next = cur; p = cur; } head.pre = p; p.next = head; //回到链表定义头开始遍历计算 p = head; int res = 0; int times = 0;//控制遍历次数 while (times < arr.length) { //是空位的话保留当前位置,向前和向后分别走一波 if (p.data == 0) { Node cur = p; int disPre = 1, disNext = 1; while (cur.pre.data != 1) { cur = cur.pre; disPre++; } cur = p; while (cur.next.data != 1) { cur = cur.next; disNext++; } res = Math.max(Math.min(disPre, disNext), res);//前距和后距的min } p = p.next; times++; } System.out.println(res); } }
字节3-14笔试第二题变体:
某单体蛋白质可以分裂为1到多个子节点,形成一颗多叉树,其中有两个节点变异为病毒,求出这俩病毒的最近的上层节点蛋白质序号,n个节点默认从0到n-1逐层排布
输入描述
4 2
2 2 3
0 2 1 2
1 1 3
4个病毒 2个分裂序列
2个致命病毒 2号和3号
0号蛋白质的2个儿子 1和2号
1号蛋白质的1个儿子 3号
15 8
2 12 14
0 3 1 2 3
1 3 4 5 6
2 1 7
3 2 8 9
4 1 10
5 1 11
6 2 12 13
10 1 14
输出结果
4 2
2 2 3
0 2 1 2
1 1 3
病毒节点2的顶层根节点0
病毒上层节点序列:0
病毒节点3的顶层根节点0
病毒上层节点序列:1 0
两病毒节点最初匹配的上层节点:0
15 8
2 12 14
0 3 1 2 3
1 3 4 5 6
2 1 7
3 2 8 9
4 1 10
5 1 11
6 2 12 13
10 1 14
病毒节点12的顶层根节点0
病毒上层节点序列:6 1 0
病毒节点14的顶层根节点0
病毒上层节点序列:10 4 1 0
两病毒节点最初匹配的上层节点:1
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int n = scanner.nextInt(); int r = scanner.nextInt(); int m = scanner.nextInt(); Integer[] virus = new Integer[m]; for (int i = 0; i < m; i++) { virus[i] = scanner.nextInt(); } //使用map保存父子关系映射 Map<Integer, Integer> mapPar = new HashMap<>(); Map<Integer, List<Integer>> mapChi = new HashMap<>(); for (int i = 0; i < r; i++) { int a = scanner.nextInt(); int b = scanner.nextInt(); List<Integer> children = new ArrayList<>(); for (int j = 0; j < b; j++) { int chi = scanner.nextInt(); children.add(chi); mapPar.put(chi, a); } mapChi.put(a, children); } //添加其余关联null的节点映射 for (int i = 0; i < n; i++) { if (!mapPar.containsKey(i)) { mapPar.put(i, null); } if (!mapChi.containsKey(i)) { mapChi.put(i, null); } } //遍历节点找出病毒节点进行溯源 Map<Integer, List<Integer>> map_virusNode_upNodes = new HashMap<>(); for (int i = 0; i < n; i++) { if (Arrays.asList(virus).contains(i)) { int savei = i; List<Integer> upNodes = new ArrayList<>(); while (mapPar.get(i) != null) { i = mapPar.get(i); upNodes.add(i); } map_virusNode_upNodes.put(savei, upNodes);//创建病毒节点的上层节点映射 System.out.println("病毒节点" + savei + "的顶层根节点" + i); System.out.print("病毒上层节点序列:"); for (int j = 0; j < upNodes.size(); j++) { System.out.print(map_virusNode_upNodes.get(savei).get(j) + " "); } System.out.println(); i = savei; } } //排查两序列找到第一次匹配的上层节点 int minLen = Integer.MAX_VALUE;//两序列的最小长度 List<List<Integer>> twoVirusUpNodes = new ArrayList<>();//逆序保存两个序列 for (Map.Entry<Integer, List<Integer>> e : map_virusNode_upNodes.entrySet()) { List<Integer> list = e.getValue(); if (list.size() < minLen) { minLen = list.size(); } Collections.reverse(list); twoVirusUpNodes.add(list); } List<Integer> virus1UpNodes = twoVirusUpNodes.get(0); List<Integer> virus2UpNodes = twoVirusUpNodes.get(1); int firstMatchUpNode = 0; for (int i = 0; i < minLen; i++) { if (virus1UpNodes.get(i) == virus2UpNodes.get(i)) { firstMatchUpNode = virus1UpNodes.get(i); continue; } } System.out.println("两病毒节点最初匹配的上层节点:" + firstMatchUpNode); } } }