基于端点递归加入间隔列表

Recursively Joining Lists of Intervals based on endpoints

我有三个区间:

10:00上午 - 11:00AM

11:00AM - 11:30AM

和3:00PM - 3:30PM

我已经编写了这个算法来递归地压缩和合并间隔,如果它们重叠或共享端点。

 public boolean optimizeIntervals(ArrayList<Interval> list) {
    ArrayList<Interval> listToOptimize = list;
    ArrayList<Interval> optimizedList = new ArrayList<Interval>();
    for (int i = 1; i < listToOptimize.size(); i++) {
        if (listToOptimize.get(i).getStart().equals(listToOptimize.get(i - 1).getEnd())) {
            optimizedList.add(new Interval(listToOptimize.get(i - 1).getStart(), listToOptimize.get(i).getEnd()));
        }else{
            optimizedList.add(new Interval(listToOptimize.get(i).getStart(), listToOptimize.get(i).getEnd()));
        }
    }
    if(optimizedList.size() == listToOptimize.size()){
        setMeetingDuringIntervals(optimizedList);
        return true;
    }else{
        optimizeIntervals(optimizedList);
    }

    return false;
}

然而,在使用调试器跟踪堆栈跟踪后,我注意到当第一次递归调用后列表的大小为 2 时,我丢失了 3:00PM 的最终 Interval - 3:30PM

如何重写该算法以不丢失我的最终值?\

我的问题是这样的:

运行 1

加入间隔 1 和 2

创建 10:00 AM - 11:30 AM

不使用 3:00PM - 3:30PM

递归调用

检查 3:00-3:30PM 是否与间隔 1 有任何重叠?

没有

只添加3:00-3:30PM

我的代码逻辑:

如果 istart time 匹配 i-1end time。将它们添加到优化列表中。

如果没有,

仅将 i 添加到优化列表。

然而,在当前的解决方案中,算法在第二个 运行 上搞砸了,从 i1 开始,只添加了 3:00 - 3:30 下午而不是第一个间隔?

所以我用这个算法解决了我的问题:

  public boolean optimizeIntervals(ArrayList<Interval> list) {
    ArrayList<Interval> listToOptimize = list;
    ArrayList<Interval> optimizedList = new ArrayList<Interval>();
    for (int i = 1; i < listToOptimize.size(); i++) {
        if(listToOptimize.size()==2){
            if (listToOptimize.get(i).getStart().equals(listToOptimize.get(i - 1).getEnd())) {
                optimizedList.add(new Interval(listToOptimize.get(i - 1).getStart(), listToOptimize.get(i).getEnd()));
            }else if(listToOptimize.get(i).getStart().isAfter(listToOptimize.get(i-1).getEnd())){
                optimizedList.add(new Interval(listToOptimize.get(i).getStart(), listToOptimize.get(i).getEnd()));
                optimizedList.add(new Interval(listToOptimize.get(i-1).getStart(), listToOptimize.get(i-1).getEnd()));
            }
        }
        else{
             if (listToOptimize.get(i).getStart().equals(listToOptimize.get(i - 1).getEnd())) {
                optimizedList.add(new Interval(listToOptimize.get(i - 1).getStart(), listToOptimize.get(i).getEnd()));
            } else if (listToOptimize.get(i).getStart().isAfter(listToOptimize.get(i - 1).getEnd())) {
                optimizedList.add(new Interval(listToOptimize.get(i).getStart(), listToOptimize.get(i).getEnd()));
            }
        }
    }
    if(optimizedList.size() == listToOptimize.size()){
        setMeetingDuringIntervals(optimizedList);
        return true;
    }else{
        optimizeIntervals(optimizedList);
    }

    return false;
}

如果存在最终连接(意味着列表大小为 2),则处理这种情况;

我不知道是否有更好的方法来处理这个问题,但它确实有效。

function compress(list) {
  if(list.length < 2) { return list; }
  // sort your interval list by the first value
  var sortedList = list.sort(function(a, b) { return a[0] - b[0]; });
  // compress your list into an result set
  var result = [sortedList[0]];
  var working = result[0];
  for(var i = 1; i < sortedList.length; i++) {
    var current = sortedList[i];
    // does the first value overlap the range?
    if(current[0] >= working[0] && current[0] <= working[1]) {
      // update the second value of the range
      working[1] = Math.max(current[1], working[1]);
    } else {
      // add a new unique range
      result.push(current);
      working = result[result.length - 1];
    }
  }
  return result;
}

var intervals = [[1,3], [3,5], [6,10], [11,13], [13,14]];
console.log(JSON.stringify(compress(intervals)));