微軟 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