剑指offer35:最小时间差
作者:互联网
题目:
给定一组范围再00:00至23:59的时间,求任意两个时间之间的最小时间差,例如输入时间数组 [“23:50”,“23:59”,“00:00”],"23:59"和"00:00"之间只有1分钟的间隔,是最小的时间差。
分析:
这道题最简单的做法就是直接第一个和第二个减,第一个和第三个减,第二个和第三个减,如果输入n个时间,则需要比较n(n-1)/2次,时间复杂度为O(n ^2)。
第二种优化的解法就是先排序,然后相邻两两相减,只需要计算O(n)个时间差,由于对n个时间排序需要O(nlogn)的时间,因此该算法总体时间复杂度是O(nlogn)。
还有一种解法可以以空间换时间,将排序步骤省掉,创建一个哈希表,哈希表的键是时间,值是true或false,true代表存在这个时间,false代表不存在这个时间,只需要计算相减相邻值为true的哈希表的键即可无需排序,一天24h折算成时间是1440分钟,用一个长度为1440的数组表示一天的时间,那么下标为0的位置对应的时间是00:00,下标为1的位置对应00:01,以此类推。
有一种特殊情况需要讨论:在计算最小时间差时,需要把排序后的最后一个时间当作第二天的时间(也就是加上24小时)与最后一个时间之间的间隔也考虑进去。例如00:01,00:04,23:59,23:59到第二天00:01只需要2min,第一天23:59到第二天00:04肯定比到00:01时间差就不用算了,所以只需要把最后一个时间当作第二天即可。
代码:
import java.util.List;
public class FindMinDifference {
public static int findMinDifference(List<String> timepoints){
// 如果输入的时间数组长度比1440还长,说明一定有重复的,因此最小时间差一定是0
if (timepoints.size() > 1440){
return 0;
}
boolean[] nums = new boolean[1440];
for(String time: timepoints){
String t[] = time.split(":");
int min = Integer.parseInt(t[0])*60 + Integer.parseInt(t[1]);
// 如果存在两个相同的时间,那么最少时间差一定是0
if (nums[min]){
return 0;
}
nums[min] = true;
}
return helper(nums);
}
private static int helper(boolean[] nums) {
int minDiff = nums.length-1;
int prev = -1;
int first = nums.length-1;
int last = -1;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i]){
if (prev >= 0){
minDiff = Math.min(i - prev,minDiff);
}
prev = i;
first = Math.min(i,first);
last = Math.max(i,last);
}
}
minDiff = Math.min(first+nums.length-last,minDiff);
return minDiff;
}
}
标签:00,nums,int,23,最小,offer35,时间,时间差 来源: https://blog.csdn.net/Jiaodaqiaobiluo/article/details/120819905