paypal 數字對生成樹

 

 

一道特別考驗語言功底的題目,首先它的輸入與輸出,對於我這種沒有處理過複雜的輸入,以及輸出的渣渣來說,浪費了大量的時間,好在現在還稍微來得及,不怕不怕啦。緊接着,整個題目的要求也是比較複雜的,首先允許存在重複的數字對,也就是說,在輸入的過程中,需要去重。若重複,則忽略。(具體實現過程中,使用一個edges的map表來去重的。)其次,順序不唯一,同樣的輸入,打亂順序後,會導致不同的輸出。比如樣例1與樣例3。

結合題意,且對於樹這種結構,首先需要確定根節點(那個沒有父節點的),其次從根節點開始能夠保證遍歷所有的節點,且僅僅遍歷一次。這就是這道題目解題的思路。而且,看題目中的要求,數字大小爲1~2^31,所以這裏不能夠使用數組了,所以可以使用map來存儲,首先需要一個鄰接表的存儲方式來存儲讀入的數據,其次需要一個字段來判斷節點是否有父節點,爲了便於實現對應不同的輸入順序有不同的輸出過程,需要增加一個時間戳標記位timestamp和深度標記位dist來表示距離根節點的距離。

緊接着就是bfs的過程了,bfs過程必然用到隊列的,所以整個過程代碼實現如下:

import java.util.*;
import java.io.*;
public class Main{
    /** 以鄰接表的形式存儲整個樹。 */
    static HashMap<Integer,ArrayList<Integer>> hh =new HashMap<>();
    /** 存下每個點的時間戳,用於確認bfs遍歷的順序 */
    static HashMap<Integer,Integer>timestamp=new HashMap<>();
    /** 節點到根節點的距離。 */
    static HashMap<Integer,Integer>dist=new HashMap<>();
    static HashMap<Integer,Boolean>has_father=new HashMap<>();
    static HashMap<Edges,Boolean>edges=new HashMap<>();
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        int n=sc.nextInt();
        while (n!=0){
            n--;
            String str[]=sc.next().split(",");
            int a=Integer.parseInt(str[0]);
            int b=Integer.parseInt(str[1]);
            /* 存儲時間戳記錄的次序 */
            int tm=0;
            Edges edge=new Edges(a,b);
            if (edges.containsKey(edge)){
                continue;//用來除去序列中重複的邊。
            }else{
                edges.put(edge,true);
            }
            if (!timestamp.containsKey(a)){
                timestamp.put(a,tm++);
            }
            if (!timestamp.containsKey(b)){
                timestamp.put(b,tm++);
            }
            has_father.put(b,true);
            if (!hh.containsKey(a)){
                ArrayList<Integer>list=new ArrayList<>();
                list.add(b);
                hh.put(a,list);
            }else{
                hh.get(a).add(b);
            }
        }
        String result=process(n);
        System.out.println(result);
    }

    private static String process(int n) {
        String result="";
        int root=-1;
        for (Integer p: hh.keySet()){
            if (has_father.get(p)==null){
                root=p;
                break;
            }
        }
        if (root==-1){
            return "Not a tree";
        }
        else{
             ArrayList<Integer>res=bfs(root);
             /* 進行寬度優先遍歷 */
            if (res.size()<timestamp.size()){
                /* 如果整個樹是不連通的,則判定不是一棵樹 */
                return "Not a tree";
            }else{
                result+=res.get(0)+"";
                for (int i=1;i<res.size();i++){
                    result+=","+res.get(i);
                }
            }
        }
        return result;
    }

    private static ArrayList<Integer> bfs(int root) {
        Queue<Integer>q=new LinkedList<>();
        q.offer(root);
        ArrayList<Integer>nodes = new ArrayList<>();
        dist.put(root,0);
        while(!q.isEmpty()){
            int t=q.poll();
            nodes.add(t);
            ArrayList<Integer>tem=hh.get(t);
             if (tem==null){
                continue;
            }
            for (Integer temp: tem){
                /* 當前節點已經被遍歷過,說明在序列中該節點存在多個父節點 */
                if (dist.containsKey(temp)){
                    return new ArrayList<>();
                }
                dist.put(temp,dist.get(t)+1);
                q.offer(temp);
            }
        }
        /*雙關鍵字排序*/
        ArrayList<ArrayList<Integer>>ans=new ArrayList<>();
        for (Integer ver:nodes){
            ArrayList<Integer>list=new ArrayList<Integer>();
            list.add(dist.get(ver));
            list.add(timestamp.get(ver));
            list.add(ver);
            ans.add(list);
        }
        nodes.clear();
        Collections.sort(ans, new Comparator<ArrayList<Integer>>() {
            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                if (Objects.equals(o1.get(0), o2.get(0))){
                    return o1.get(1)-o2.get(1);
                }
                return o1.get(0)-o2.get(0);
            }
        });
        for (ArrayList<Integer>t:ans){
            nodes.add(t.get(2));
        }
        return nodes;
    }

}
class Edges{
    int first;
    int second;
    public Edges(int first,int second){
        this.first=first;
        this.second=second;
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章