其他分享
首页 > 其他分享> > 剑指offer35:最小时间差

剑指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