#1490 : Tree Restoration

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

  1. Which nodes are leaves  
  2. The distance (number of edges) between any pair of leaves
  3. The depth of every node (the root's depth is 1)
  4. For the nodes on the same level, their order from left to right

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.
tree-restoration.png
輸入
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

測試

分析

首先,給出的測試用例太過簡單,先構建一個複雜的測試用例:
Paste_Image.png
從下往上,從左往右遍歷:
第六層(最下層):
第一個節點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

解答

解法1:結果是Wrong Answer,然而並不知道爲何,誰能幫我看看錯在哪了哇~

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

31 6 13 1 4 6 7 7 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 3 8 12 15 19 21 23 26 27 28 29 30 31 0 3 4 4 5 5 5 6 6 6 6 6 6 3 0 3 5 4 4 6 5 7 7 7 7 7 4 3 0 6 5 5 7 6 8 8 8 8 8 4 5 6 0 7 7 7 8 4 4 8 8 8 5 4 5 7 0 4 8 3 9 9 9 9 9 5 4 5 7 4 0 8 5 9 9 9 9 9 5 6 7 7 8 8 0 9 9 9 7 7 7 6 5 6 8 3 5 9 0 10 10 10 10 10 6 7 8 4 9 9 9 10 0 2 10 10 10 6 7 8 4 9 9 9 10 2 0 10 10 10 6 7 8 8 9 9 7 10 10 10 0 2 4 6 7 8 8 9 9 7 10 10 10 2 0 4 6 7 8 8 9 9 7 10 10 10 4 4 0
相關文章
相關標籤/搜索