java判断两个时间段是否有交集_如何判断两个时间段是否有交集

给定两个左闭右开时间段 [A, B)、[X, Y),如何判断它们是否有交集?

由于时间可以转换为时间戳,时间戳是一个数字,所以我们可以将问题转换为:如何判断两个左闭右开的数字区间是否有交集。

结论是如果 X < B AND A < Y,那么有交集,证明过程见下方。

数轴示意图

这是一个不完善的、不容易思考的证明。

我将他们想象成数轴上的两段:

-------A.------B。------X.-------Y。------

“.” 表示闭区间,“。”表示开区间。

然后令 [A, B) 不动,向左一直移动 [X, Y)。先是 X 进入 [A, B),然后是 X 离开 [A, B),Y 进入 [A, B)。所以只要 X 或 Y 在 [A, B) 间,那么两者有交集。

上述算法遗漏了两种情况,[X, Y) 完全在 [A, B) 中或者[A, B) 完全在 [X, Y) 中:

[X, Y) 完全在 [A, B):

-----A.-----X.----Y。----B。-----

所以这种证明方法不好,虽然比较形象,但是因为变量太多,容易遗漏。

使用排列组合[1]

使用排列组合获取所有的可能情况,并定义当前数小于等于下一个数字(因为这样定义就能包含所有的情况):

Python 代码:

from itertools import permutations

for x in list(permutations('ABXY')):

# 由于 A < B,X < Y,所以 A 的位置一定在 B 前面,X 的位置一定在 Y 前面

if x.index('A') < x.index('B') and x.index('X') < x.index('Y'):

print(x)

上方的输出为:

('A', 'B', 'X', 'Y') # 因为 [A, B) 的最大值 < B 然后 B < X,然后 X 是 [X, Y) 的最小值,所以 [A, B) 的最大值小于 [X, Y) 的最小值,所以两者无交集。

('A', 'X', 'B', 'Y') # 当 X = B 时,无交集,其余情况有交集。

('A', 'X', 'Y', 'B') # 有交集

('X', 'A', 'B', 'Y') # 有交集

('X', 'A', 'Y', 'B') # 当 A = Y 时,无交集,其余情况有交集

('X', 'Y', 'A', 'B') # 无交集,与第一个的证明类似

所以无交集的所有可能情况是,A <= B <= X <= Y、X = B、A = Y、X <= Y <= A <= B。由于 A < B、X < Y,所以只要 B <= X,那么 A <= X,所以 A <= B <= X <= Y 变为 B <= X <= Y,同理可得 X <= Y <= A <= B => Y <= A <= B。去除条件自带的 A < B、X < Y 的情况后,为 B <= X、X = B、A = Y、Y <= A,由于 B <= X 包含 X = B,Y <= A 包含 Y= A,所以 B <= X 或 Y <= A,对其取反,得到有交集的情况:X < B AND A < Y。

这里的证明是通过排列组合,获取了所有的情况,然后从整理所有没有交集的情况(更少的情况),然后推导出规律。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值