【问题标题】:Maximal Nested Intervals Set最大嵌套区间集
【发布时间】:2014-04-27 07:49:21
【问题描述】:

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

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

我是这样想的:- 让我们举个例子- (0,7) (0,5) (1,21) (1,9) (2,8) (2,4) (3, 20) (4,16) (5,15) (6,21) 对它进行排序,使得 a[i-1]=b[i] 比从第一个区间开始,我们开始一个链表..如果下一个区间在一个区间内,我们向下移动节点并遍历沿着节点创建的图(除了主列表)..我们将最大级别节点的指针存储在这个图可以适应新的区间..并在链表中进一步遍历以查看当前区间来自谁..最后我们有一个指向我们必须附加当前区间的节点的指针..并比较这个节点的级别与我们已经拥有的最大级别......最大级别的最终值是最大嵌套间隔集的大小..

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

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

【问题讨论】:

  • 如果你不想写那么多(按 B-A, [A,B] 之间的距离对它们进行排序),请在 N^2 中执行,然后执行 2 个 for 循环。为了获得更好的复杂性,您必须创建一些日期结构。你的建议是一个小时的工作+测试。
  • @IonescuRobert 我不明白你提出的解决方案。您按大小对间隔进行排序,然后这两个循环做什么?

标签: algorithm sorting nested complexity-theory intervals


【解决方案1】:

编辑:该问题的一些解决方案已发布here,包括两个声称为 O(n lg n) 的解决方案。但是,我认为 O(n lg n) 解决方案不起作用。我在那个页面上做了 cmets 来说明原因。如果有人有 O(n lg n) 的解决方案,我很乐意听到。

二次解

这个问题可以用动态规划在 O(n^2) 时间内解决:

  1. 计算每个区间包含多少个区间(可以通过两个嵌套循环完成)
  2. 按包含区间数的升序对区间进行排序
  3. 使用递归MaxNestedIntervals解决问题

*注意: 步骤 1 可以使用此处的解决方案在 O(n lg n) 时间内完成:Sub O(n^2) algorithm for counting nested intervals? 步骤 2 可以使用任何基于比较的最佳排序算法在 O(n lg n) 时间内完成。 可能有办法优化第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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-15
    • 2012-08-06
    • 2013-08-22
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    相关资源
    最近更新 更多