Minifiying作为整数数组的范围列表

时间:2017-06-06 16:12:37

标签: java algorithm range

我有这样的代码

public List<int[]> getMinifiedRanges(List<int[]> ranges) {
    for (int[] range : ranges) {

    }
}

我的目标是压缩范围列表,由包含范围大于&amp;的整数数组表示。下界

离。 [100,200] [250,350] - 此示例将返回相同的输入,因为没有重叠

[100,200] [150,350] [400,500] - 这将返回[100,350] [400,500],因为第二个范围下限在第一个范围内是包含的,因此返回的范围将具有它的上限扩展到350 - 注意当输入是3个数组时它只返回两个数组。

我无法弄清楚如何从当前范围中检索先前的范围,以便我可以扩展下限或上限。

3 个答案:

答案 0 :(得分:1)

一旦您对范围进行了排序(按分钟,然后按最大值),每组重叠范围将组合在一起,这样您就可以通过列表检查每个范围与最后一个合并范围。

public static List<int[]> getMinifiedRanges(List<int[]> ranges) {
    List<int[]> minRanges = new ArrayList<>();
    if (ranges.isEmpty()) return minRanges;

    List<int[]> sorted = new ArrayList<>(ranges); // don't modify input list
    Collections.sort(sorted, Comparator.<int[]>comparingInt(r -> r[0]).thenComparingInt(r -> r[1]));

    int[] last = sorted.get(0);
    for (int[] next : sorted.subList(1, sorted.size())) {
        if (last[1] < next[0]) {
            minRanges.add(last);
            last = next;
        } else if (next[1] > last[1]) {
            last = new int[] { last[0], next[1] };
        }
    }
    minRanges.add(last);

    return minRanges;
}

答案 1 :(得分:0)

首先,您可以根据以下形式拆分每个范围:

[a,b]范围 - &gt; (a,1)和(b,2)对

将这些对存储在列表中,然后对列表进行排序。排序后,你可以迭代列表,当一对像(x,1)来增加一个变量,当一对像(x,2)来减少那个变量。变量从0到1的位置是起始索引,变量从1变为0的位置是完成索引。

答案 2 :(得分:0)

第一次脸红,寻找阵列停止相交的地方。通过此实现,您需要在新的“合并”列表中创建最后一个范围...

List<int[]> ranges = new ArrayList<>(); //holds the original list of ranges
int[] current;
int[] previous;
List<int[]> merged = new ArrayList<>(); //will end up with the merged ranges
int max = ranges.size() - 1;
int start = 0;
for (int i = 1; i <= max; i++) {
  previous = ranges.get(i-1);
  current = ranges.get(i);
  if (current[0] > previous[1]) {
    merged.add(new int[] {ranges.get(start)[0], previous[1]});
    start = i;
  }
}
merged.add(new int[] {ranges.get(start)[0], ranges.get(max)[1]});