给定一个区间列表表示所有整数,如果它们确实相交或重叠,则应该可以将它们折叠成一个区间,否则给定的区间不受影响。比如说,如果输入是 egI [(2-6), (1-4), (8-12)],那么预期的输出是 [(1-6), (8-12)] eg II [(4- 7), (2-6), (1-4), (8-12), (7-9)] 预期的输出是 [(1-12)]。
更正:错过了排序部分,所以是的,它是 O(nlogn) 时间而不是 O(n)。感谢您指出了这一点。我已经编写并测试了一个有效的 O(nlogn) 时间和 O(2n) 空间算法方法。在下面分享这种方法的代码。我有兴趣听到解决这个问题的不同方法,可能更有效。
//假设每个区间,(2-6)等都表示为“Interval”对象(类定义如下图),其中low = 2 and high = 6 // Step1:按给定的低端点排序间隔 // Step2:找到排序间隔的并集
//输入:
List<Interval> intervalList = new ArrayList<Interval>();
//输出:
List<Interval> unionList = new ArrayList<Interval>();
private static final Comparator<Interval> Low_EPSorter = new LowEPSorter();
class Interval {
int low, high;
Interval(int l, int h, int m) {
low = l;
high = h;
}
}
////-------BEGIN:找到给定区间的并集的方法----//////
void UnionOfIntervals() {
//Find intersection and combine intervals as necessary
int sz = intervalList.size();
// sort by low endpoint
Collections.sort(intervalList, Low_EPSorter);
for(int i = 0; i < sz; i++) {
int j = i;
if(j > 0) {
if( Intervals.intersect(intervalList.get(j), intervalList.get(j-1)) ) {
Interval v = union(intervalList.get(j), intervalList.get(j-1));
checkAndAdd(v, unionList);
}
else {
if(i == 1) {
unionList.add(intervalList.get(j-1));
unionList.add(intervalList.get(j));
}
else {
unionList.add(intervalList.get(j));
}
} //No intersection
} //If 2 elements atleast
}
//Print intervals after union
System.out.println("Input intervals after sorting:");
for(Interval v : intervalList) {
System.out.print(v.low + "," + v.high + " ");
}
System.out.println();
System.out.println("Union of intervals:");
for(Interval v : unionList) {
System.out.print(v.low + "," + v.high + " ");
}
}
void checkAndAdd(Interval x, List t) {
int top = t.size()-1;
if( top >=0 && Intervals.intersect(unionList.get(top), x) ) {
Interval v = union(unionList.get(top), x);
t.remove(top);
t.add(v);
}
else {
t.add(x);
}
}
////-------END:找到给定区间的并集的方法----//////
////--- 辅助方法 --- ////
static boolean intersect(Interval a, Interval b) {
boolean r = false;
if(b.high < a.low || b.low > a.high)
r = false;
else if(a.low <= b.high && b.low <= a.high)
r = true;
return r;
}
Interval union(Interval a, Interval b) {
int l = (a.low < b.low) ? a.low : b.low;
int max = (a.high > b.high) ? a.high : b.high;
return new Interval(l, max);
}
private static class LowEPSorter implements Comparator<Interval> {
public int compare(Interval a, Interval b) {
int r = 0;
if(a.low < b.low)
r = -1;
else if(a.low > b.low)
r = 1;
return r;
}
}