最大嵌套间隔集

时间:2012-10-15 12:58:39

标签: algorithm sorting nested complexity-theory intervals

这是一个基于查找最大嵌套间隔集大小的问题。

有许多区间,每个区间由包含起点和终点(si,ei)的对定义。如果i2完全位于i1内,则两个间隔i1和i2称为嵌套。示例: - (2,6)和(3,4)是嵌套的,因为(3,4)是(2,6)的一部分。类似地,k个区间i1,i2,i3 ...... ik被称为嵌套,如果,i2位于i1内,i3位于i2内,......等等。根据给定的间隔确定最大间隔集的大小,以便该集合中的所有间隔都可以生成嵌套。

我按照以下方式思考: - 让我们采取例如 - (0,7)(0,5)(1,21)(1,9)(2,8)(2,4)(3, 20)(4,16)(5,15)(6,21)按照a [i-1]< = a [i]&& b [i-1]> = b [i]从第一个区间开始我们开始一个链表..如果下一个区间进入一个区间,我们向下移动节点并遍历在节点下创建的图形(除了主list)..我们将最大级别节点的指针存储在此图中新间隔可以适合的位置..并在链表中进一步遍历以查看当前间隔来自谁...最后我们有一个指向节点的指针我们必须附加当前间隔..并将此节点的级别与我们已有的最大级别进行比较.....最大级别的最终值是设置的最大嵌套间隔的大小。

上述解决方案的复杂性很可能是: - O(n(k + l)+ nlogn)

我想这很难得到它,但我没有其他选择...如果有人有任何其他算法来解决它...请发布因为我的算法需要更长的时间来实现(很多数据结构)参与)...谢谢!!!

1 个答案:

答案 0 :(得分:0)

编辑:问题的一些解决方案已发布here,其中包括两个声称为O(n lg n)的解决方案。但是,我不认为O(n lg n)解决方案有效。我在该页面上发表评论,说明原因。如果有人有O(n lg n)解决方案,我很乐意听到。

二次解决方案

使用动态编程可以在O(n ^ 2)时间内解决此问题:

  1. 计算每个间隔包含的间隔数(可以使用两个嵌套循环完成)
  2. 按所包含间隔数的升序对间隔进行排序
  3. 使用重复MaxNestedIntervals来解决问题
  4. *注: 步骤1可以使用此处的解决方案在O(n lg n)时间内完成:Sub O(n^2) algorithm for counting nested intervals? 可以使用任何基于比较的最佳排序算法在O(n lg n)时间内完成步骤2。 可能有一种方法可以优化第3步,但我还没有找到它。


    <强>复发

    MaxNestedIntervals(i) =
        max {j = 0 to i-1} :
            1 + MaxNestedIntervals(j)    if interval i contains interval j
            0                            if interval i doesn't contain interval j
    

    基本情况

    MaxNestedIntervals(i) =
        0    if interval i contains 0 intervals
        1    if interval i contains 1 interval
    

    示例代码

    import java.util.*;
    
    public class MaxNestedIntervals {
        public static void main(String[] args) {
            Interval[] intervals = new Interval[10];
            intervals[0] = new Interval(0, 7);
            intervals[1] = new Interval(0, 5);
            intervals[2] = new Interval(1, 21);
            intervals[3] = new Interval(1, 9);
            intervals[4] = new Interval(2, 8);
            intervals[5] = new Interval(2, 4);
            intervals[6] = new Interval(3, 20);
            intervals[7] = new Interval(4,16);
            intervals[8] = new Interval(5,15);
            intervals[9] = new Interval(6,21);
    
            int n = intervals.length;
            AugmentedInterval[] augmentedIntervals = new AugmentedInterval[n];
    
            for (int i = 0; i < n; i++) {
                augmentedIntervals[i] = new AugmentedInterval(intervals[i]);
            }
    
            for (int i = 0; i < n; i++) {
                AugmentedInterval outerInterval = augmentedIntervals[i];
    
                for (int j = 0; j < n; j++) {
                    if (i == j) {
                        continue;
                    }
    
                    AugmentedInterval innerInterval = augmentedIntervals[j];
    
                    if (outerInterval.contains(innerInterval)) {
                        outerInterval.numContainedIntervals++;
    
                        if (outerInterval.childInterval == null) {
                            outerInterval.childInterval = innerInterval;
                        }
                    }
                }
            }
    
            Arrays.sort(augmentedIntervals, new Comparator<AugmentedInterval>() {
                public int compare(AugmentedInterval i, AugmentedInterval j) {
                    return i.numContainedIntervals - j.numContainedIntervals;
                }
            });
    
            int maxNestedIntervals = 0;
            AugmentedInterval parentInterval = null;
    
            for (int i = 0; i < n; i++) {
                AugmentedInterval currentInterval = augmentedIntervals[i];
    
                if (currentInterval.numContainedIntervals == 0) {
                    currentInterval.maxNestedIntervals = 0;
                } else if (currentInterval.numContainedIntervals == 1) {
                    currentInterval.maxNestedIntervals = 1;
                } else {
                    int maxNestedIntervalsForCurrentInterval = 0;
    
                    for (int j = 0; j < i; j++) {
                        AugmentedInterval candidateNestedInterval = augmentedIntervals[j];
                        int maxNestedIntervalsForCurrentCandidate = candidateNestedInterval.maxNestedIntervals + 1;
    
                        if (currentInterval.contains(candidateNestedInterval) && maxNestedIntervalsForCurrentCandidate >= maxNestedIntervalsForCurrentInterval) {
                            maxNestedIntervalsForCurrentInterval = maxNestedIntervalsForCurrentCandidate;
                            currentInterval.childInterval = candidateNestedInterval;
                        }
                    }
    
                    currentInterval.maxNestedIntervals = maxNestedIntervalsForCurrentInterval;
    
                    if (maxNestedIntervalsForCurrentInterval >= maxNestedIntervals) {
                        maxNestedIntervals = maxNestedIntervalsForCurrentInterval;
                        parentInterval = currentInterval;
                    }
                }
            }
    
            if (n == 0) {
                System.out.println("The largest set of nested intervals is the empty set.");
            } else if (maxNestedIntervals == 0) {
                System.out.println("The largest set of nested intervals has 1 interval.\n");
                System.out.println("That interval is:");
            } else {
                System.out.println("The largest set of nested intervals has " + (maxNestedIntervals + 1) + " intervals.\n");
                System.out.println("Those intervals are:");
            }
    
            for (AugmentedInterval currentInterval = parentInterval; currentInterval != null; currentInterval = currentInterval.childInterval) {
                System.out.println(currentInterval);
            }
    
            System.out.println();
        }
    
        private static class Interval implements Comparable<Interval> {
            public int start = 0;
            public int end = 0;
    
            public Interval(int start, int end) {
                this.start = start;
                this.end = end;
            }
    
            public int size() {
                return this.end - this.start;
            }
    
            public boolean contains(Interval other) {
                return (this.start <= other.start && this.end >= other.end);
            }
    
            public int compareTo(Interval other) {
                return this.size() - other.size();
            }
    
            public String toString() {
                return "[" + this.start + ", " + this.end + "]";
            }
        }
    
        private static class AugmentedInterval extends Interval {
            public int numContainedIntervals = 0;
            public int maxNestedIntervals = 0;
            public AugmentedInterval childInterval = null;
    
            public AugmentedInterval(Interval interval) {
                super(interval.start, interval.end);
            }
        }
    }