我有这样的代码
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个数组时它只返回两个数组。
我无法弄清楚如何从当前范围中检索先前的范围,以便我可以扩展下限或上限。
答案 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]});