gpt4 book ai didi

java - 排除重叠间隔

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:23:11 25 4
gpt4 key购买 nike

我有两个间隔列表。我想从 list1 中删除已经存在于 list2 中的所有时间。例子: list 1:

[(0,10),(15,20)]

list 2:

[(2,3),(5,6)]

输出:

[(0,2),(3,5),(6,10),(15,20)]

有什么提示吗?

当时尝试删除一个间隔,但似乎我需要采取不同的方法:

public List<Interval> removeOneTime(Interval interval, Interval remove){
List<Interval> removed = new LinkedList<Interval>();
Interval overlap = interval.getOverlap(remove);
if(overlap.getLength() > 0){
List<Interval> rms = interval.remove(overlap);
removed.addAll(rms);
}
return removed;
}

最佳答案

我会用扫描线算法来解决这个问题。间隔的起点和终点是事件,它们被放入优先级队列中。您只需从左向右移动,在每个事件处停止,并根据该事件更新当前状态。

为了简单起见,我做了一个小实现,其中使用了以下 Interval 类:

public class Interval {
public int start, end;

public Interval(int start, int end) {
this.start = start;
this.end = end;
}

public String toString() {
return "(" + start + "," + end + ")";
}
}

前面提到的事件点由以下类表示:

public class AnnotatedPoint implements Comparable<AnnotatedPoint> {
public int value;
public PointType type;

public AnnotatedPoint(int value, PointType type) {
this.value = value;
this.type = type;
}

@Override
public int compareTo(AnnotatedPoint other) {
if (other.value == this.value) {
return this.type.ordinal() < other.type.ordinal() ? -1 : 1;
} else {
return this.value < other.value ? -1 : 1;
}
}

// the order is important here: if multiple events happen at the same point,
// this is the order in which you want to deal with them
public enum PointType {
End, GapEnd, GapStart, Start
}
}

现在,剩下的就是构建队列并进行扫描,如下面的代码所示

public class Test {

public static void main(String[] args) {
List<Interval> interval = Arrays.asList(new Interval(0, 10), new Interval(15, 20));
List<Interval> remove = Arrays.asList(new Interval(2, 3), new Interval(5, 6));

List<AnnotatedPoint> queue = initQueue(interval, remove);
List<Interval> result = doSweep(queue);

// print result
for (Interval i : result) {
System.out.println(i);
}
}

private static List<AnnotatedPoint> initQueue(List<Interval> interval, List<Interval> remove) {
// annotate all points and put them in a list
List<AnnotatedPoint> queue = new ArrayList<>();
for (Interval i : interval) {
queue.add(new AnnotatedPoint(i.start, PointType.Start));
queue.add(new AnnotatedPoint(i.end, PointType.End));
}
for (Interval i : remove) {
queue.add(new AnnotatedPoint(i.start, PointType.GapStart));
queue.add(new AnnotatedPoint(i.end, PointType.GapEnd));
}

// sort the queue
Collections.sort(queue);

return queue;
}

private static List<Interval> doSweep(List<AnnotatedPoint> queue) {
List<Interval> result = new ArrayList<>();

// iterate over the queue
boolean isInterval = false; // isInterval: #Start seen > #End seen
boolean isGap = false; // isGap: #GapStart seen > #GapEnd seen
int intervalStart = 0;
for (AnnotatedPoint point : queue) {
switch (point.type) {
case Start:
if (!isGap) {
intervalStart = point.value;
}
isInterval = true;
break;
case End:
if (!isGap) {
result.add(new Interval(intervalStart, point.value));
}
isInterval = false;
break;
case GapStart:
if (isInterval) {
result.add(new Interval(intervalStart, point.value));
}
isGap = true;
break;
case GapEnd:
if (isInterval) {
intervalStart = point.value;
}
isGap = false;
break;
}
}

return result;
}
}

这导致:

(0,2)
(3,5)
(6,10)
(15,20)

关于java - 排除重叠间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16304245/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com