微软 2017春招真题java
There is a tree of N nodes which are numbered from 1 to N. Unfortunately, its edges are missing so we don't know how the nodes are connected. Instead we know: node
Can you restore the tree's edges with these information? Note if node u is on the left of node v, u's parent should not be on the right of v's parent.
输入
The first line contains three integers N, M and K. N is the number of nodes. M is the depth of the tree. K is the number of leaves.
The second line contains M integers A1, A2, ... AM. Ai represents the number of nodes of depth i.
Then M lines follow. The ith of the M lines contains Ai numbers which are the nodes of depth i from left to right.
The (M+3)-th line contains K numbers L1, L2, ... LK, indicating the leaves.
Then a K × K matrix D follows. Dij represents the distance between Li and Lj.1 ≤ N ≤ 100
输出
For every node from 1 to N
output its parent. Output 0 for the root's parent.
样例输入
8 3 5
1 3 4
1
2 3 4
5 6 7 8
3 5 6 7 8
0 3 3 3 3
3 0 2 4 4
3 2 0 4 4
3 4 4 0 2
3 4 4 2 0
样例输出
0 1 1 1 2 2 4 4
测试
首先,给出的测试用例太过简单,先构建一个复杂的测试用例:
从下往上,从左往右遍历:
第六层(最下层):
第一个节点26,其父节点必定是第五层第一个非叶子节点20。同时,在距离矩阵中增长节点20,与其余节点距离为节点26与其余节点距离-1
第二个节点27,若和26的距离为2,则其父节点也是20(×),不然,其父节点是第五层第二个非叶子节点22(√)同时,在距离矩阵中增长节点22,与其余节点距离为节点27与其余节点距离-1
第三个节点28,若和27的距离为2,则其父节点也是22(√),不然,其父节点是第五层第三个非叶子节点24(×)
......
第六层遍历结束,明确了第六层全部节点的父节点,也将第五层全部非叶子节点加入距离矩阵
第五层(倒数第二层):
第一个节点19,其父节点必定是第四层第一个非叶子节点13。同时,在距离矩阵中增长节点13,与其余节点距离为节点19与其余节点距离-1
第二个节点20,若和19的距离为2,则其父节点也是13(√),不然,其父节点是第四层第二个非叶子节点14(×)
......
第五层遍历结束,明确了第五层全部节点的父节点,也将第五层全部非叶子节点加入距离矩阵
......
(一直遍历到第三层)this
第二层:
全部节点的父节点都是根节点(第一层的惟一节点)rest
第一层:
根节点的父节点为0
code
import java.util.Scanner; import java.util.Map; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; public class Main_2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt();//节点数8 int m = sc.nextInt();//树深度3 int k = sc.nextInt();//叶子树5 int[] a = new int[m];//深度为i的节点数 int[][] arr = new int[m][];//每行的节点data Node[][] nodes = new Node[m][];//每行的节点 Map<Integer, Node> nodesMap = new LinkedHashMap<>();//存节点 Map<Node, Map<Node,Integer>> distanceMap = new ConcurrentHashMap<>();//存节点间距离(叶子+非叶子) for (int i = 0; i < m; i++) { a[i] = sc.nextInt(); arr[i] = new int[a[i]]; nodes[i] = new Node[a[i]]; } for (int i = 0; i < m; i++) { for (int j = 0; j < a[i]; j++){ arr[i][j] = sc.nextInt(); nodes[i][j] = new Node(); nodes[i][j].data = arr[i][j]; nodes[i][j].level = i + 1; nodesMap.put(arr[i][j],nodes[i][j]); if(i == 0){ nodes[i][j].parent = null; } else if(i == 1){ nodes[i][j].parent = nodes[0][0]; } } } int[] l = new int[n];//叶子 3 5 6 7 8 for(int i = 0; i < k; i++){ l[i] = sc.nextInt(); nodesMap.get(l[i]).isLeaf = true; } int[][] d = new int[n][n];//叶子节点间距离 for (int i = 0; i < k; i++) { Map<Node, Integer> tempMap = new ConcurrentHashMap<>(); for (int j = 0; j < k; j++){ d[i][j] = sc.nextInt(); if (l[i] < l[j]){ tempMap.put(nodesMap.get(l[j]),d[i][j]); distanceMap.put(nodesMap.get(l[i]),tempMap); } } } //从下往上,从左往右遍历 for(int i = m - 1; i >= 2; i--){ int ii = i - 1;//上一层 int jj = 0;//上一层第0个节点 Node lastNode = null; for(int j = 0; j < a[i]; j++){ if (lastNode != null){//不是本层第一个节点,计算该节点与本层上一个节点的距离 int distance = (distanceMap.get(lastNode) != null && distanceMap.get(lastNode).get(nodes[i][j]) != null) ? distanceMap.get(lastNode).get(nodes[i][j]) : distanceMap.get(nodes[i][j]).get(lastNode); if (distance == 2){ nodes[i][j].parent = lastNode.parent; continue; } } while (nodes[ii][jj].isLeaf){ jj++; } nodes[i][j].parent = nodes[ii][jj]; //在距离矩阵中增长其父节点 Iterator it1 = distanceMap.entrySet().iterator(); while (it1.hasNext()) { Map.Entry outerEntry = (Map.Entry) it1.next(); Node outerKey = (Node) outerEntry.getKey(); Map<Node,Integer> outerValue = (Map<Node,Integer>) outerEntry.getValue(); if(outerKey == nodes[i][j]){ Map<Node, Integer> tempMap = new ConcurrentHashMap<>(); Iterator it2 = outerValue.entrySet().iterator(); while (it2.hasNext()) { Map.Entry entry = (Map.Entry) it2.next(); Node innerKey = (Node) entry.getKey(); Integer innerValue = (Integer) entry.getValue(); tempMap.put(innerKey,innerValue - 1); } distanceMap.put(nodes[i][j].parent,tempMap); } else{ Iterator it2 = outerValue.entrySet().iterator(); while (it2.hasNext()) { Map.Entry entry = (Map.Entry) it2.next(); Node innerKey = (Node) entry.getKey(); Integer innerValue = (Integer) entry.getValue(); if(innerKey == nodes[i][j]){ Map<Node, Integer> tempMap = distanceMap.get(outerKey); tempMap.put(nodes[i][j].parent,innerValue - 1); distanceMap.put(outerKey,tempMap); } } } } lastNode = nodes[i][j]; jj++; } } for (Map.Entry<Integer, Node> entry : nodesMap.entrySet()) { Node thisNode = entry.getValue(); int result = (thisNode.parent != null) ? thisNode.parent.data : 0; System.out.print(result+" "); } } } class Node{ public Node parent; public int data; public int level; public boolean isLeaf; }
附两个测试用例:
9 4 6
1 2 3 4
9
1 10
2 3 4
5 6 7 8
3 5 6 7 8 10
0 3 3 3 3 3
3 0 2 4 4 4
3 2 0 4 4 4
3 4 4 0 2 4
3 4 4 2 0 4
3 4 4 4 4 0
orm