在其范围内每个间隔的最大重叠次数

时间:2016-11-01 19:22:34

标签: algorithm

给出间隔列表

[[0,30],[1,5],[6,10],[11,15],[16,20],[21,25]]

每个列表的第一个元素是开始时间,第二个元素是结束时间。

我们看到0 - 30与所有其他5个区间重叠,而所有其他区间仅与另一个区间重叠一次,因此最大重叠次数为5。

我在网上看到很多关于找到会议或火车所需的平台或房间数量的答案

http://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/

http://www.zrzahid.com/maximum-number-of-overlapping-intervals/

但是我不知道这些算法是如何适用于这个问题的,因为我已经尝试了算法,他们将返回2作为此示例输入列表所需的平台和房间数量,因为他们将尝试在特定时间找到最大重叠次数,但我想知道在整个时间间隔内可能发生的最大重叠次数。

下面是我的暴力方法,它可行,但如果可能的话,如何将运行时间最小化为O(nlogn)?

function maxNumConflict(intervals) {
    max = 0;
    for (var i = 0; i < intervals.length; i++) {
        tempMax = 0;
        for (var j = i + 1; j < intervals.length; j++) {
            if (overlap(intervals[i], intervals[j])) {
                tempMax++;
            }
        }
        max = Math.max(tempMax, max);
    }
    return max;
}

function overlap(i1, i2) {
    return ((i1[0] >= i2[0] && i1[0] < i2[1])
         || (i2[0] >= i1[0] && i2[0] < i1[1]));
}
console.log(maxNumConflict(([[0,30],[1,5],[6,10],[11,15],[16,20], [21,25]])));

2 个答案:

答案 0 :(得分:2)

让我们修复一个时间间隔[L, R]。考虑任意间隔[a, b]。如果出现以下情况,则这两个间隔不重叠:

  1. b < L
  2. a > R
  3. 请注意,任何间隔最多只能满足这两个条件中的一个。因此,对于[L, R]区间,它重叠的区间数等于N - c1 - c2 - 1,其中N是区间总数,c1是区间的数量满足条件1,c2是满足条件2的区间数。

    如何快速找到c1c2

    如果我们有一个按其右边界排序的所有间隔的列表,c1等于第一个间隔的位置(按排序顺序),使其右边界不小于L 。我们可以使用二进制搜索找到它。

    在按左边界排序的间隔列表上使用二进制搜索,我们可以找到c2(其间隔数减去第一个间隔的位置,使其左边界大于{{1} })。

    我们需要在此处对两个大小为R的列表进行排序,并对它们进行2次二进制搜索N次。因此,时间复杂度为N

答案 1 :(得分:1)

下面是我的问题代码,这个概念有效,但没有检查二进制搜索的边界条件。

// nlogn solution
// Solution is not correct, got error boundary condition on binary search, but the concep works
function findMaxOverlap(times) {

    var arrSize = times.length;
    var max = 0;
    var start = [];
    var end = [];

    // Split the times list into start time list and end time list
    for (var i = 0; i < times.length; i++) {
        start.push(times[i][0]);
        end.push(times[i][1]);
    }

    // Sort them
    start.sort(compare);
    end.sort(compare)

    // Find the number of overlapping for each interval
    for (var i = 0; i < arrSize; i++) {
        max = Math.max(max, findMaxHelper(start, end, times[i], arrSize));
    }

    return max;

}

function compare(a,b) {
    if (a < b) {
        return -1;
    } else if (a > b) {
        return 1;
    }
    return 0;
}


function findMaxHelper(startArr, endArr, interval, arrSize) {

    // Num of element that do not overlap with current interval
    var c1 = 0;         // Num of element that has their start time >= current end time 
    var c2 = 0;         // Num of element that has their end time =< current start time 

    c1 = arrSize - binarySearch(startArr, interval[1]);
    c2 = binarySearch(endArr, interval[0]);

    var overlap = arrSize - c1 - c2 - 1;
    return overlap;

}


// Find the index of the element that is >= or =< than time
function binarySearch(arr, time) {

    var low = 0;
    var high = arr.length;
    var mid = high / 2;

    while (low <= high) {
        var mid = Math.round(low + (high - low) / 2);

        if (arr[mid] > time) {  
            high = mid - 1;
        } else if (arr[mid] < time) {
            low = mid + 1;
        }  else {
            return mid;
        }

    }
    return Math.round(low + (high - low) / 2);
}