539. 最小时间差(中等)
给定一个 24 小时制(小时:分钟 “HH:MM”)的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。
示例 1:
输入:timePoints = [“23:59”,“00:00”]
输出:1
示例 2:
输入:timePoints = [“00:00”,“23:59”,“00:00”]
输出:0
提示:
-
2 <= timePoints <= 2 * 104
-
timePoints[i]
格式为 “HH:MM”
思路
第一时间想到排序,然后直接取相邻两个时间点之间的最小差值;正常比较取最小差值这也就结束了;但是对于时间点
而言,我们需要考虑最大时间和最小时间之间的差值大于720分钟的情况。
u1s1到这代码逻辑就OK了,不过还有一个优化点:按题意,一共有 24 60=24×60=1440 种不同的时间;根据鸽巢原理,如果集合长度大于1440,则必有两个相同的时间,直接返回0即可。
代码
class Solution {
/**
* 方法:排序 + 鸽巢原理
* 时间复杂度:O( min(n,1440) log( min(n,1400) ) )
* 空间复杂度:O( min(n,1440) ) <--> 排序使用到的栈空间
*/
public int findMinDifference(List<String> timePoints) {
int len = timePoints.size();
// 最多有1440种时间,如果大于1440说明必有两个相同的时间
if (len > 1440) {
return 0;
}
Collections.sort(timePoints);
int time0 = getMinutes(timePoints.get(0));
int res = Integer.MAX_VALUE;
int prev = time0;
for (int i = 1; i < len; i++) {
int curr = getMinutes(timePoints.get(i));
res = Math.min(res, curr - prev);
prev = curr;
}
// 兼容首尾时间差值大于720(半圈)的情况;
return Math.min(res, time0 - prev + 1440);
}
private int getMinutes(String hhMM) {
return ((hhMM.charAt(0) - '0') * 10 + hhMM.charAt(1) - '0') * 60
+ (hhMM.charAt(3) - '0') * 10 + hhMM.charAt(4) - '0';
}
}