判断两个事件是否存在冲突

178 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

🎈算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 -> 判断两个事件是否存在冲突

题目描述

给你两个字符串数组 event1 和 event2 ,表示发生在同一天的两个闭区间时间段事件,其中:

event1 = [startTime1, endTime1] 且 event2 = [startTime2, endTime2] 事件的时间为有效的 24 小时制且按 HH:MM 格式给出。

当两个事件存在某个非空的交集时(即,某些时刻是两个事件都包含的),则认为出现 冲突 。

如果两个事件之间存在冲突,返回 true ;否则,返回 false 。

示例 1:

输入:event1 = ["01:15","02:00"], event2 = ["02:00","03:00"]
输出:true
解释:两个事件在 2:00 出现交集。

示例 2:

输入:event1 = ["01:00","02:00"], event2 = ["01:20","03:00"]
输出:true
解释:两个事件的交集从 01:20 开始,到 02:00 结束。

示例 3:

输入:event1 = ["10:00","11:00"], event2 = ["14:00","15:00"]
输出:false
解释:两个事件不存在交集。

提示:

  • evnet1.length == event2.length == 2.
  • event1[i].length == event2[i].length == 5
  • startTime1 <= endTime1
  • startTime2 <= endTime2
  • 所有事件的时间都按照 HH:MM 格式给出

思路分析

首先我们要先理解一下题目的意思,题目会给我们两个数组,每个数组中包含两个HH:MM格式的时间,代表两个时间段,我们需要判断给出的这两个时间段是否有重合的部分。

首先我们可以先分析一下有哪些情况下两个时间段不会有交集:

  • 1、时间段1的起始时间大于时间段2的结束时间

image.png

  • 2、时间段1的结束时间小于时间段2的起始时间

image.png

那么我们在比较时间的时候通常都会怎么比较呢?一般来说我们都是会将时间转化成同一单位的数值再进行比较,如1:151:30,我们可以转换成1.25h1.5h或者75s90s再进行比较,这样可以直接得出答案,所以我们可以写出一下代码:

/**
 * @param {string[]} event1
 * @param {string[]} event2
 * @return {boolean}
 */
 var haveConflict = function(event1, event2) {
    const start1 = parseInt(event1[0].split(':')[0]) * 60 + parseInt(event1[0].split(':')[1]);
    const end1 = parseInt(event1[1].split(':')[0]) * 60 + parseInt(event1[1].split(':')[1]);
    const start2 = parseInt(event2[0].split(':')[0]) * 60 + parseInt(event2[0].split(':')[1]);
    const end2 = parseInt(event2[1].split(':')[0]) * 60 + parseInt(event2[1].split(':')[1]);
    return !(start1 > end2 || end1 < start2);
};

那么有没有更简便的写法呢?我们可以看到在提示中有这么一条:所有事件的时间都按照 HH:MM 格式给出,什么是HH:MM 格式呢?就是会对不满2位数的小时和分钟进行补零操作,如:1:20会写成01:20。那这点有什么用呢?我们可以看一下下面这两个例子:

  • '11:20' > '2:20' -> false
  • '11:20' > '02:20' -> true

看到这里我们还需要了解一下字符串的大小比较方式:

两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。

所以“11:20”和“2:20”比较是首先比较第一个字符即'1'和'2',比较之后发现后者的ASCII码更大就直接返回比较结果了,不会再比较后面的字符了。

所以在不满两位数的时间前面补零可以使相同位数的时间处于同一个比较的位置,这样得出的比较结果即是我们想要的结果了,所以我们的代码可以简化成以下这样:

/**
 * @param {string[]} event1
 * @param {string[]} event2
 * @return {boolean}
 */
 var haveConflict = function(event1, event2) {
    return !(event1[0] > event2[1] || event2[0] > event1[1]);
};

完整AC代码如下:

AC代码


/**
 * @param {string[]} event1
 * @param {string[]} event2
 * @return {boolean}
 */
 var haveConflict = function(event1, event2) {
    return !(event1[0] > event2[1] || event2[0] > event1[1]);
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。