zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
    
  • 相关阅读:
    详述@Responsebody和HTTP异步请求的关系
    利用synchronized解析死锁的一种形成方式
    初识Spring JdbcTemplate
    初识SpringIOC
    JasperReport框架使用教程(附带常见空白页问题说明)
    LeetCode~1033.移动石子直到连续
    LeetCode~941.有效的山脉数组
    LeetCode~344. 反转字符串
    Job for network.service failed because the control process exited with error code问题
    LeetCode~报数(简单)
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7741090.html
Copyright © 2011-2022 走看看