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

时间:2015-08-06 18:33:24

标签: algorithm jodatime intervals

我有三个间隔:

上午10:00 - 上午11:00

上午11:00 - 上午11:30

和下午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.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}}的下午3:00 - 下午3:30

如何重写该算法以避免失去最终值?\

这就是我对我的问题的意思:

RUN 1

加入间隔1和2

创建上午10:00 - 上午11:30

请不要在下午3:00 - 下午3:30

递归召唤

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

没有

仅在3:00-3:30 PM添加

我的代码逻辑:

如果Interval i匹配start time&#39; s i-1。将它们添加到优化列表中。

如果没有,

仅将end time添加到优化列表中。

然而,在目前的解决方案中,算法会在i开始时从i开始第二次运行,并且仅在下午3:00 - 3:30而不是第一个时间间隔?

2 个答案:

答案 0 :(得分:1)

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

{{1}}

如果存在最终连接(意味着列表大小为2),则处理该案例;

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

答案 1 :(得分:1)

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)));