剑指 Offer II 035. 最小时间差

96 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

1. 题目与解析

给定一个 24 小时制(小时:分钟  "HH:MM" )的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。

输入: timePoints = ["23:59","00:00"]

输出: 1

输入: timePoints = ["00:00","23:59","00:00"]

输出: 0

根据题意,我们可以首先将数组按照字典序进行排序,之后计算每两个相邻元素间的差值,取最小值,需要注意的是,排序后的列表的开头与结尾的时间间隔要单独进行计算:

  1. 对数组进行排序;
  2. 遍历计算元素间的差值;
    • 在这一部分计算时,直接计算正序间的差值就可以了。
  3. 单独计算开头与结尾间的差值。
    • 这一部分要反向计算两个时间点的差值,即先计算00:00list[0]的时间间隔,再加上list[len-1]24:00的时间间隔。

2. 题解

  1. 字典序排序,Java中可以直接借助Collections.sort()完成。
Collections.sort(timePoints);
  1. 遍历计算时间差值,计算的核心是(hh - h) * 60 + (mm - m)
int h = Integer.valueOf(timePoints.get(0).substring(0, 2)),
    m = Integer.valueOf(timePoints.get(0).substring(3, 5)), 
    ans = Integer.MAX_VALUE,
    flg = h * 60 + m;

for (int i = 1; i < timePoints.size(); i++) {
    String timePoint = timePoints.get(i);

    int hh = Integer.valueOf(timePoint.substring(0, 2)),
        mm = Integer.valueOf(timePoint.substring(3, 5)),
        val = (hh - h) * 60 + (mm - m);    

    ans = Math.min(ans, val);
    h = hh;
    m = mm;
}
  1. 单独计算开头与结尾间的差值,这一部分是最特殊的,这里我们需要知道,步骤2是按照顺时针的顺序计算的差值,再计算头尾间隔时,顺时针的结果有可能会大于逆时针的结果,而且,就算是顺时针的结果小于逆时针结果,那顺时针的结果也肯定比步骤2中的都要大,所以我们在这一步只需要考虑逆时针的结果。
ans = Math.min(ans, flg + 1440 - (h * 60 + m));

整体的代码如下所示:

class Solution {
    public int findMinDifference(List<String> timePoints) {
        Collections.sort(timePoints);

        int h = Integer.valueOf(timePoints.get(0).substring(0, 2)),
            m = Integer.valueOf(timePoints.get(0).substring(3, 5)), 
            ans = Integer.MAX_VALUE,
            flg = h * 60 + m;

        for (int i = 1; i < timePoints.size(); i++) {
            String timePoint = timePoints.get(i);

            int hh = Integer.valueOf(timePoint.substring(0, 2)),
                mm = Integer.valueOf(timePoint.substring(3, 5)),
                val = (hh - h) * 60 + (mm - m);    

            ans = Math.min(ans, val);
            h = hh;
            m = mm;
        }

        ans = Math.min(ans, flg + 1440 - (h * 60 + m));

        return ans;
    }
}