难度中等5
给定一个 24 小时制(小时:分钟 "HH:MM")的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。
示例 1:
输入:timePoints = ["23:59","00:00"] 输出:1
示例 2:
输入:timePoints = ["00:00","23:59","00:00"] 输出:0
提示:
2 <= timePoints.size() <= 2 * 10^4
timePoints[i]
格式为 "HH:MM"
思路:本题只有小时和分钟,所以总共合法的时间只有24 * 60 = 1440个。
A.如果timePoints.size() > 1440,那么必定会有重复的,所以最小时间差肯定是0。
B.如果timePoints.size() > 720,在timePoints.size() = 720的时候,我们可以保证最小间隔的最大值为2[隔点取值],当然这一点对于解题帮助没那么大,毕竟timePoints.size() > 720的时候,最小间隔可以是0。
C.否则我们需要将字符串格式的时间转换为分钟数后排序计算。值得注意的是,本题存在一种坑点,即不保证所有的时间是同一天的,例如00:00与23:50,如果00:00算做当天的0点,那么差距就是1439,但如果00:00算作第二天的0点,那么差距只有1。因此我们的算法如下:
A.将所有的时间转成具体分钟数
B.将时间按照分钟数大小排序
C.在数组的尾巴插入1440+times[0]
D.对于times[i],计算时间差times[i]-times[i-1]
E.维护时间差的最小值就是答案~
现在重点证明C和D,C的操作就是考虑到了时间隔了一天这种情况,并且在当天时间固定的情况下,第二天的时间越早,二者的差距就越小,所以只需要1440(一天的分钟数)+times[0]。然而如果考虑到D,会发现我们只计算了times[n]-times[n-1]这一种跨天的情况,那么是正确的吗?是的,证明如下,我们想要隔天的时间的差尽可能的小,那么可以拆成两部分,一部分是今天的剩余时间,一部分是明天的时间,要想使得今天的剩余时间变小,那么就要求今天的当前时间尽可能大,同理明天的时间要尽可能早。
class Solution {
public:
int time2int(string time){
return ((time[0] - '0') * 10 + (time[1] - '0')) * 60 + (time[3] - '0') * 10 + (time[4] - '0');
}
int findMinDifference(vector<string>& timePoints) {
if(timePoints.size() > 1440) return 0;
vector<int> times;
int time, max_diff = 1440;
for(string timePoint:timePoints){
time = time2int(timePoint);
times.push_back(time);
}
sort(times.begin(), times.end());
times.push_back(times[0] + 1440);
for(int i = 1; i < times.size(); ++ i){
max_diff = min(max_diff, times[i] - times[i - 1]);
}
return max_diff;
}
};