「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
给定一个 24 小时制(小时:分钟 "HH:MM" )的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。
示例 1:
输入:timePoints = ["23:59","00:00"]
输出:1
示例 2:
输入:timePoints = ["00:00","23:59","00:00"]
输出:0
方法一:排序
将 timePoints 排序后,最小时间差必然出现在 timePoints 的两个相邻时间,或者 timePoints 的两个首尾时间中。因此排序后遍历一遍 timePoints 即可得到最小时间差。
var findMinDifference = function(timePoints) {
timePoints.sort();
let ans = Number.MAX_VALUE;
// 保存第一个数,方便后面和最后一个数进行比较
let t0Minutes = getMinutes(timePoints[0]);
let preMinutes = t0Minutes;
// 计算相邻两个数的差值
for (let i = 1; i < timePoints.length; ++i) {
const minutes = getMinutes(timePoints[i]);
ans = Math.min(ans, minutes - preMinutes); // 相邻时间的时间差
preMinutes = minutes;
}
ans = Math.min(ans, t0Minutes + 1440 - preMinutes); // 首尾时间的时间差
return ans;
};
// 将"HH:MM"形式转换成分钟的形式
const getMinutes = (t) => {
return ((t[0].charCodeAt() - '0'.charCodeAt()) * 10 + (t[1].charCodeAt() - '0'.charCodeAt())) * 60 + (t[3].charCodeAt() - '0'.charCodeAt()) * 10 + (t[4].charCodeAt() - '0'.charCodeAt());
}
复杂度分析
- 时间复杂度:O(nlogn),其中 n 是数组 timePoints 的长度。排序需要 O(nlogn) 的时间。
- 空间复杂度:O(logn)。排序需要 O(logn) 的栈空间。
方法二:鸽巢原理
根据题意,一共有 24×60=1440 种不同的时间。由鸽巢原理可知,如果 timePoints 的长度超过 1440,那么必然会有两个相同的时间,此时可以直接返回 0。
var findMinDifference = function(timePoints) {
const n = timePoints.length;
if (n > 1440) {
return 0;
}
timePoints.sort();
let ans = Number.MAX_VALUE;
let t0Minutes = getMinutes(timePoints[0]);
let preMinutes = t0Minutes;
for (let i = 1; i < n; ++i) {
const minutes = getMinutes(timePoints[i]);
ans = Math.min(ans, minutes - preMinutes); // 相邻时间的时间差
preMinutes = minutes;
}
ans = Math.min(ans, t0Minutes + 1440 - preMinutes); // 首尾时间的时间差
return ans;
};
const getMinutes = (t) => {
return ((t[0].charCodeAt() - '0'.charCodeAt()) * 10 + (t[1].charCodeAt() - '0'.charCodeAt())) * 60 + (t[3].charCodeAt() - '0'.charCodeAt()) * 10 + (t[4].charCodeAt() - '0'.charCodeAt());
}
复杂度分析
- 时间复杂度:,其中 n 是数组 timePoints 的长度,C=24×60=1440。由于当 n>C 时直接返回 0,排序时的 n 不会超过 C,因此排序需要 的时间。
- 空间复杂度:O(logmin(n,C))。排序需要 O(logmin(n,C)) 的栈空间。