lintcode605- Sequence Reconstruction- medium- airbnb google

Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. The org sequence is a permutation of the integers from 1 to n, with 1 ≤ n ≤ 10^4. Reconstruction means building a shortest common supersequence of the sequences in seqs (i.e., a shortest sequence so that all sequences in seqs are subsequences of it). Determine whether there is only one sequence that can be reconstructed from seqs and it is the org sequence.

Given org = [1,2,3], seqs = [[1,2],[1,3]]
Return false
Explanation:
[1,2,3] is not the only one sequence that can be reconstructed, because [1,3,2] is also a valid sequence that can be reconstructed.

Given org = [1,2,3], seqs = [[1,2]]
Return false
Explanation:
The reconstructed sequence can only be [1,2].

Given org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
Return true
Explanation:
The sequences [1,2], [1,3], and [2,3] can uniquely reconstruct the original sequence [1,2,3].

Given org = [4,1,5,2,6,3], seqs = [[5,2,6,3],[4,1,5,2]]
Return true

算法:题目很长,要你实现的就是确保两件事:

1.从seqs里的边的关系有且只有一种引出的构造方式 ==> (用queue.size() == 1循环条件的BFS,最后判断list.size() == org.length? 因为某个时间如果queue的size>1了,那说明有多种排列方式,中断掉以后最后的拓扑序就不够长了)

2.这种构造出来的答案和org吻合上 (拓扑序里加入内容时直接对比org对应位置的内容)

数据结构:Map<Integer, Integer> indegrees, Map<Integer, Set<Integer>> edges 拓扑序辅助, Queue<Integer> queue BFS容器, List<Integer> order 结果容器

细节:1. 当传入边关系是null,空,几个空的情况下要回false(可在初始化block里面用count计数,更elegant,如九章题解)。2.拓扑序题小心输入重复边的情况,在同时初始化Indegree和edges的时候小心,两个数字得同步加上去。如果数据结构edges用set,set自动去重了,那你indegree得要求之前没加过这条边的情况下才能++,这才实现同步;或者两个都用矩阵,一起把重复边都加上去也是没关系的。3.存储的edges关系只用加进所有相邻两个数字pair就够了,1-3-2里的1-2关系已经隐含在1-3 + 3-2里面了。

 

1.自己实现(corner case不elegant)

public class Solution {
    /*
     * @param org: a permutation of the integers from 1 to n
     * @param seqs: a list of sequences
     * @return: true if it can be reconstructed only one or false
     */
    public boolean sequenceReconstruction(int[] org, int[][] seqs) {
        // write your code here
        // 两个条件可以确保:
        // 1.从seqs里的边的关系有且只有一种引出的构造方式(queue.size() == 1的BFS)
        // 2.这种构造出来的答案和org吻合上(对比构造的order和org)
        
        Map<Integer, Integer> indegrees = new HashMap<Integer, Integer>();
        Map<Integer, Set<Integer>> edges = new HashMap<Integer, Set<Integer>>();
        
        //全在avoid seqs是[] [[], []]这种case,很不elegant,用count好点
        if ((seqs == null || seqs.length == 0) && org.length != 0) {
            return false;
        }
        boolean hasEdge = false;
        for (int i = 0; i < seqs.length; i++) {
            if (seqs[i].length != 0) {
                hasEdge = true;
            }
        }
        if (!hasEdge && org.length != 0) {
            return false;
        }
        
        //初始化
        for (int i = 1; i <= org.length; i++) {
            indegrees.put(i, 0);
            edges.put(i, new HashSet<Integer>());
        }
        
        //填入seqs信息
        for (int[] seq : seqs) {
            if (seq.length > 0 && (seq[0] <= 0 || seq[0] > org.length)) {
                    return false;
            }
            for (int i = 1; i < seq.length; i++) {
                int prev = seq[i - 1];
                int next = seq[i];
                if (next <= 0 || next > org.length) {
                    return false;
                }
                // 细节:避免seqs里有重复边,你也加了额外的indegree
                if (edges.get(prev).add(next)) {
                    indegrees.put(next, indegrees.get(next) + 1);
                }
            }
        }
        
        // BFS初始化
        Queue<Integer> queue = new LinkedList<Integer>();
        List<Integer> order = new ArrayList<Integer>();
        for (int i = 1; i <= org.length; i++) {
            if (indegrees.get(i) == 0) {
                queue.offer(i);
            }
        }
        
        // BFS生成拓扑序
        int pointer = 0;
        // **重点,确保seqs只能排出一种排列
        while (queue.size() == 1) {
            int prev = queue.poll();
            order.add(prev);
            if (org[pointer++] != prev) {
                return false;
            }
            for (int next : edges.get(prev)) {
                indegrees.put(next, indegrees.get(next) - 1);
                if (indegrees.get(next) == 0) {
                    queue.offer(next);
                }
            }
        }
        
        // 与while条件配合使用
        return order.size() == org.length;
    }
}

 

2.九章实现:

public class Solution {
    /**
     * @param org a permutation of the integers from 1 to n
     * @param seqs a list of sequences
     * @return true if it can be reconstructed only one or false
     */
    public boolean sequenceReconstruction(int[] org, int[][] seqs) {
        // Write your code here
        Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
        Map<Integer, Integer> indegree = new HashMap<Integer, Integer>();
        
        for (int num : org) {
            map.put(num, new HashSet<Integer>());
            indegree.put(num, 0);
        }

        int n = org.length;
        int count = 0;
        for (int[] seq : seqs) {
            count += seq.length;
            if (seq.length >= 1 && (seq[0] <= 0 || seq[0] > n))
                return false;
            for (int i = 1; i < seq.length; i++) {
                if (seq[i] <= 0 || seq[i] > n)
                    return false;
                if (map.get(seq[i - 1]).add(seq[i]))
                    indegree.put(seq[i], indegree.get(seq[i]) + 1);
            }
        }

        // case: [1], []
        if (count < n)
            return false;
        
        Queue<Integer> q = new ArrayDeque<Integer>();
        for (int key : indegree.keySet()) 
            if (indegree.get(key) == 0)
                q.add(key);
        
        int cnt = 0;
        while (q.size() == 1) {
            int ele = q.poll();
            for (int next : map.get(ele)) {
                indegree.put(next, indegree.get(next) - 1);
                if (indegree.get(next) == 0) q.add(next);
            }
            if (ele != org[cnt]) {
                return false;
            }
            cnt++;
        }
        
        return cnt == org.length;
    }
}

 


posted @ 2017-10-27 04:49  jasminemzy  阅读(242)  评论(0编辑  收藏  举报