查找与给定数字/间隔重叠的所有间隔

时间:2019-01-16 21:25:42

标签: java intervals

我知道这是一个定义明确的问题,通常可以通过间隔树来解决。我找到了解决方法here。但是我对此仍有一些疑问。

方法I:使用间隔树,时间复杂度O(logN + K),其中N是间隔的总数,K是重叠间隔的数量。

(1)我们如何选择中心点? Wiki并未真正提及选择,而link则提及“此树中的分区值也基于中位数,但中值取自所有间隔的2N个端点。”根据我的理解,我们选择中心点以使间隔树“平衡”。但是,如果是这种情况,这是否意味着间隔树无法自平衡(因为它取决于中心点的选择)?

方法II:构建哈希图。时间复杂度O(1)

我觉得此方法使用相交间隔作为键,并使用与该相交对应的间隔列表作为值。例如,给定间隔[1,3]和[2,4],哈希映射的键将是[1,2],[2,3],[3,4],值将是[1、2 ] => {[1,3]},[2,3] => {[1,3],[2,4]},[3,4] => {[2,4]}。

我的问题是

(1)在上面的示例中,如果我们查询number = 2怎么办,那么有两个包含2的交集间隔,我们如何知道要返回的值?

(2)如果一个交集间隔类似于[2,2],我们是否应该将其用作单独的键?我发现很难分析两种情况。一个是交点的开始=结束,另一个是输入间隔包含两个相同的间隔,例如[1,2]和[1,2]

任何帮助将不胜感激!

如果需要,下面是我对解决方案2的代码

Map<Interval, List<Interval>> map;
private void init(List<Interval> input) {
    // step 1 sort input

    // step 2:
    PriorityQueue<Interval> minHeap = new PriorityQueue<>(new Comparator<Interval>() {
        @Override
        public int compare(Interval o1, Interval o2) {
            return o1.end - o2.end;
        }
    });
    Map<Interval, List<Interval>> map = new HashMap<>();
    int start = 0; // init should be redundant
    for (int i = 0; i < input.size(); i++) {
        Interval cur = input.get(i);
        if (minHeap.isEmpty()) {
            start = input.get(i).start;
            minHeap.offer(cur);
        } else if (minHeap.peek().end < cur.start) { // [] both start and end are inclusive
            List<Interval> values = new ArrayList<>(minHeap);
            Interval min = minHeap.poll();
            map.put(new Interval(start, min.end), values);
            i--;
            start = min.end;
        } else {
            minHeap.offer(cur);
            map.put(new Interval(start, cur.start), new ArrayList<>(minHeap));
            start = cur.start;
        }
    }
    // pop until the pq is empty
    while (!minHeap.isEmpty()) {
        List<Interval> values = new ArrayList<>(minHeap);
        Interval cur = minHeap.poll();
        map.put(new Interval(start, cur.end), values);
    }
    this.map = map;
}

0 个答案:

没有答案