思路
- 暴力法就是挨个计算 因此是O(n²)
- 在此基础上优化 可以先排序再计算相邻的时间间隔 O(nlogn)
- 继续优化,因为排序的目的就是为了计算相邻时刻的时间间隔,因为题目中的时刻仅仅有60*24(1440)个,所以可以直接开一个长度为1440的boolean数组,用true代表有此时刻,那么相邻的时间间隔就是index2 - index1
在此基础上有三点需要注意- 首先是输入时刻数目的长度,如果大于1440,那么必然有重复的,可以直接返回0
- 其次是我们在改变数组内容时可以先检查一下该索引是不是true,如果是的话说明有相同时刻,可以直接返回0
- 最后是我们在计算相邻两个时刻的时间差时,还需要考虑头和尾,需要把index1+1400-index2,也就是计算一下最后一个时刻距离第二天第一个时刻的时间差,ex:[00:00,01:00,23:59],最小时间间隔不是60,而是1
class Solution {
public int findMinDifference(List<String> timePoints) {
//必然会有重复的时间
if (timePoints.size() > 1440)
return 0;
boolean[] minutesFlag = new boolean[1440];
for (String time : timePoints) {
String[] timePoint = time.split(":");
int minute = Integer.parseInt(timePoint[0]) * 60 + Integer.parseInt(timePoint[1]);
if(minutesFlag[minute])
return 0;
minutesFlag[minute] = true;
}
int minSpacing = Integer.MAX_VALUE, first = 1440, last = 0, pre = -1;
for (int i = 0; i < minutesFlag.length; i++) {
if (minutesFlag[i]) {
if (pre > 0)
minSpacing = Math.min(minSpacing, i - pre);
pre = i;
first = Math.min(first, i);
last = Math.max(last, i);
}
}
return Math.min(minSpacing, 1440 + first - last);
}
}
由于时间的特殊性,在计算间隔的时候需要额外计算跨天的时间,所以才会有
min := 1440 - minutes[len(minutes)-1] + minutes[0]
Go代码
func findMinDifference(timePoints []string) int {
if len(timePoints) >= 1440 {
return 0
}
minutes := make([]int, len(timePoints))
for i, time := range timePoints {
hour, _ := strconv.Atoi(time[0:2])
minute, _ := strconv.Atoi(time[3:])
minutes[i] = hour*60 + minute
}
sort.Ints(minutes)
min := 1440 - minutes[len(minutes)-1] + minutes[0]
for i := 0; i < len(minutes)-1; i++ {
if minutes[i+1]-minutes[i] < min {
min = minutes[i+1] - minutes[i]
}
}
return min
}