美文网首页
从Interval 建图

从Interval 建图

作者: 尚无花名 | 来源:发表于2019-05-23 21:32 被阅读0次

某非一线大厂电面题,
电面的时候我没写出最优解,估计炸了。没签NDA 我来分析一下这道题。
题目比较新,结合了interval和图。
题意是这样的。
给你一堆interval, 每个interval有start time, end time, 和label.
两个interval A, B 之间在如下条件下有edge。

  1. B在A的右边而且没有overlap
  2. A 和 B之间不能再塞入一个别的interval (这个interval是从输入的list里面的。 如果输入的list里面有这样的interval,则没有edge)
    输出是一个建好的图把所有合法的边都连起来。

面试官浑厚的东欧口音很影响理解题意。
我尝试了两种办法都没有找出最优解。
我先尝用interval的思路试图先sort再从左到右只扫一遍,发现没法弄因为第二个条件有时候会miss掉。
后来又尝试先按第一个条件建图,再DFS删掉2里面不合法的边,被面试官打断了。
他说了一下暴力解,让我写代码了,时间复杂度是 O(N^3).
暴力解是这样对任何两个interval, 先看有没有overlap,再扫描整个list,看能不能塞进第三个interval。
教训应该就是立马写暴力解。写完暴力解再说。

后来面完想了一阵才想到最优解。
最优解应该是这样的。
1。 先把所有interval按start时间排序。
2。从左到右扫
a. 对每一个interval i , 先找到他右边第一个不和它overalp的interval. (可以用binary search来优化)
b. 从第一个non overlap的interval开始往右扫,保留并一直新一个当前最小的end time,当扫到某一个interval的start 时间大于等于这个最小的end time时就停止,之前的所有node都可以和 interval i有边。之后的都没有边。
时间复杂度是 O(N log N + V + E)
where n is the number of spans, V is the vertex number ,E is edge.
In worst case scenario, it is O(n^2).

public class BuildGraph {

    public List<Node> buildGraph(List<Span> spans) {
        // Build all the graph node
        List<Node> graph = new ArrayList<>();
        Collections.sort(spans, new Comparator<Span>() {
            @Override
            public int compare(Span o1, Span o2) {
                return o1.start - o2.start;
            }
        });
       for (Span span : spans) {
            graph.add(new Node(span));
        }
        for (int i = 0; i < graph.size() - 1; i++) {
            Node node = graph.get(i);
            // binary search to find the first node has the starting point >= current node end point.
            int pointer = firstNonOverlap(graph, i);

            // starting from pointer, linear scan with early termination;
            // how many points we need to do depends on the number of edges;
            int curEnd = Integer.MAX_VALUE;
            while (pointer < graph.size()) {
                Node curNode = graph.get(pointer);
                if (curNode.span.start >= curEnd) break; // early termination
                else {
                    node.connectTo(curNode);
                    curEnd = Math.min(curEnd, curNode.span.end); // update the min ending position.
                }
                pointer++;
            }
        }
        return graph;
    }
    // binary search to find the first Node that non overlap with nodes at index i;
    private int firstNonOverlap(List<Node> graph, int i) {
        int end = graph.get(i).span.end;
        int l = i + 1, r = graph.size() - 1;

        while (l < r) {
            int m = l + (r - l) / 2;
            if (graph.get(m).span.start >= end) r = m;
            else l = m + 1;
        }
        if (graph.get(r).span.start < end) {
            return r + 1;
        } else return r;

    }

    class Node {
        Span span;
        Set<Node> children;

        void connectTo(Node that) {
            this.children.add(that);
        }

    public Node(Span span) {
        this.span = span;
        children = new HashSet<>();
    }
}
    class Span {
        String label;
        int start;
        int end;

        public Span(String label, int start, int end) {
            this.label = label;
            this.start = start;
            this.end = end;
        }
    }
}


相关文章

网友评论

      本文标题:从Interval 建图

      本文链接:https://www.haomeiwen.com/subject/solizqtx.html