You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算含起止日期的对象数组中重叠日期范围的最大数量

最优解法:扫描线算法

这个算法的时间复杂度为O(n log n),是求解区间最大重叠数的标准最优方案,远优于暴力两两比对的*O(n²)*方案。

实现思路

  • 把每个时间区间拆成两个事件:开始时间对应权重+1(表示新增一个重叠区间),结束时间对应权重-1(表示减少一个重叠区间)
  • 对所有事件排序:优先按时间戳升序排列,若时间戳相同,默认把结束事件排在开始事件前,避免把「前一区间结束时间等于后一区间开始时间」的情况误判为重叠
  • 遍历排序后的事件,实时统计当前重叠数,同步更新最大重叠数即可

代码实现

function getMaxOverlap(intervals) {
  // 生成事件数组
  const events = []
  intervals.forEach(interval => {
    const startTs = new Date(interval.start_date).getTime()
    const endTs = new Date(interval.end_date).getTime()
    events.push({ time: startTs, delta: 1 })
    events.push({ time: endTs, delta: -1 })
  })

  // 事件排序
  events.sort((a, b) => {
    if (a.time !== b.time) return a.time - b.time
    // 如需将「结束时间等于开始时间」判定为重叠,把下方返回值改为 b.delta - a.delta 即可
    return a.delta - b.delta
  })

  let currentOverlap = 0
  let maxOverlap = 0
  for (const event of events) {
    currentOverlap += event.delta
    maxOverlap = Math.max(maxOverlap, currentOverlap)
  }

  return maxOverlap
}

// 测试示例数据
const testData = [
  { start_date: '2021-01-01 10:00:00', end_date: '2021-01-01 11:00:00'},
  { start_date: '2021-01-01 08:00:00', end_date: '2021-01-01 11:00:00'},
  { start_date: '2021-01-01 12:00:00', end_date: '2021-01-01 14:00:00'},
  { start_date: '2021-01-01 12:30:00', end_date: '2021-01-01 14:30:00'},
  { start_date: '2021-01-01 14:00:00', end_date: '2021-01-01 17:30:00'},
]
console.log(getMaxOverlap(testData))
// 默认规则输出2,调整同时间排序优先级后输出3,匹配你提到的示例预期

内容的提问来源于stack exchange,提问作者Daniel Barnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:06:03