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

如何实现日程空闲时段有效性验证算法(JS/Go)

高效时段冲突验证算法实现(JavaScript + Go 版本)

问题描述

给定一组无重叠且已按开始时间排序的忙碌时间区间(毫秒时间戳),验证待新增的时段是否可以安排(即与所有已有区间无重叠)。

核心思路

因为区间已按开始时间升序排列,我们可以用二分查找快速定位可能冲突的区间,将时间复杂度从线性遍历的O(n)优化到O(log n),适合处理大规模区间场景。

冲突判定规则:
新增时段 [inc.start, inc.end] 与某区间 [slot.start, slot.end] 冲突的条件是:
inc.start < slot.end && inc.end > slot.start
反之,只要新增时段与所有区间都不满足该条件,即可安排。

需覆盖的边缘情况:

  • 忙碌区间列表为空
  • 新增时段完全在所有区间之前/之后
  • 新增时段与已有区间刚好相邻(如新增时段结束时间等于某区间开始时间)
  • 新增时段的开始时间等于结束时间(无时长,视为可安排)
  • 新增时段开始时间大于结束时间(参数非法,返回false)

JavaScript 实现

const timeslots = [
  { start: 10, end: 14 },
  { start: 17, end: 21 },
  { start: 30, end: 37 },
  // ... 可添加更多区间
];
// 确保区间按开始时间升序排列(若输入未排序,此步骤必须执行)
const sortedSlots = timeslots.sort((a, b) => a.start - b.start);

const checkValid = (inc) => {
  // 参数合法性校验
  if (typeof inc.start !== 'number' || typeof inc.end !== 'number' || inc.start > inc.end) {
    return false;
  }
  // 空区间列表直接返回可安排
  if (sortedSlots.length === 0) {
    return true;
  }

  let left = 0;
  let right = sortedSlots.length - 1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    const current = sortedSlots[mid];

    // 检查当前区间是否与新增时段冲突
    if (inc.start < current.end && inc.end > current.start) {
      return false;
    }

    // 新增时段在当前区间左侧,去左半区排查
    if (inc.end <= current.start) {
      right = mid - 1;
    } else {
      // 新增时段在当前区间右侧,去右半区排查
      left = mid + 1;
    }
  }

  // 遍历完所有可能区间,无冲突
  return true;
};

// 测试用例
console.log(checkValid({ start: 15, end: 16 })); // true(无重叠)
console.log(checkValid({ start: 15, end: 18 })); // false(与[17,21]重叠)
console.log(checkValid({ start: 16, end: 27 })); // false(与[17,21]重叠)
console.log(checkValid({ start: 8, end: 39 })); // false(覆盖多个区间)
// 边缘情况测试
console.log(checkValid({ start: 14, end: 17 })); // true(刚好相邻)
console.log(checkValid({ start: 0, end: 9 })); // true(在所有区间之前)
console.log(checkValid({ start: 38, end: 40 })); // true(在所有区间之后)
console.log(checkValid({ start: 21, end: 30 })); // true(区间间隙)
console.log(checkValid({ start: 5, end: 5 })); // true(无时长)
console.log(checkValid({ start: 20, end: 15 })); // false(参数非法)

Go 实现

package main

import (
	"fmt"
	"sort"
)

// Slot 定义时间区间结构
type Slot struct {
	Start int64
	End   int64
}

// CheckValid 验证新增时段是否可安排
func CheckValid(sortedSlots []Slot, inc Slot) bool {
	// 参数合法性校验
	if inc.Start > inc.End {
		return false
	}
	if len(sortedSlots) == 0 {
		return true
	}

	left, right := 0, len(sortedSlots)-1
	for left <= right {
		mid := (left + right) / 2
		current := sortedSlots[mid]

		// 检查冲突
		if inc.Start < current.End && inc.End > current.Start {
			return false
		}

		if inc.End <= current.Start {
			right = mid - 1
		} else {
			left = mid + 1
		}
	}
	return true
}

func main() {
	timeslots := []Slot{
		{Start: 10, End: 14},
		{Start: 17, End: 21},
		{Start: 30, End: 37},
	}
	// 确保区间排序(若输入未排序)
	sort.Slice(timeslots, func(i, j int) bool {
		return timeslots[i].Start < timeslots[j].Start
	})

	// 测试用例
	fmt.Println(CheckValid(timeslots, Slot{15, 16}))  // true
	fmt.Println(CheckValid(timeslots, Slot{15, 18}))  // false
	fmt.Println(CheckValid(timeslots, Slot{16, 27}))  // false
	fmt.Println(CheckValid(timeslots, Slot{8, 39}))   // false
	fmt.Println(CheckValid(timeslots, Slot{14, 17}))  // true
	fmt.Println(CheckValid(timeslots, Slot{0, 9}))    // true
	fmt.Println(CheckValid(timeslots, Slot{38, 40}))  // true
	fmt.Println(CheckValid(timeslots, Slot{21, 30}))  // true
	fmt.Println(CheckValid(timeslots, Slot{5, 5}))    // true
	fmt.Println(CheckValid(timeslots, Slot{20, 15}))  // false
}

内容的提问来源于stack exchange,提问作者P A S H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:25:19