最小时间差

标签: 数组 数学 字符串 排序

难度: Medium

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

示例 1:

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

示例 2:

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

提示:

  • 2 <= timePoints.length <= 2 * 104
  • timePoints[i] 格式为 "HH:MM"

注意:本题与主站 539 题相同: https://leetcode-cn.com/problems/minimum-time-difference/

Submission

运行时间: 31 ms

内存: 17.8 MB

def getMinutes(t: str) -> int:
    return (int(t[0]) * 10 + int(t[1])) * 60 + int(t[3]) * 10 + int(t[4])

class Solution:
    def findMinDifference(self, timePoints: List[str]) -> int:
        n = len(timePoints)
        if n > 1440:
            return 0
        timePoints.sort()
        ans = 1440
        t0Minutes = getMinutes(timePoints[0])
        preMinutes = t0Minutes
        for i in range(1, n):
            minutes = getMinutes(timePoints[i])
            ans = min(ans, minutes - preMinutes)  # 相邻时间的时间差
            preMinutes = minutes
        ans = min(ans, t0Minutes + 1440 - preMinutes)  # 首尾时间的时间差
        return ans

Explain

这个题解的核心思路是首先将输入的时间列表按照时间顺序排序,然后计算排序后相邻时间点之间的差值,最后还需要检查首尾时间点的差值以处理跨天的情况。考虑到最多只有1440种不同的分钟表示(24小时*60分钟),如果输入的时间点数量超过1440,则必定存在重复,即最小时间差为0。具体步骤为:1. 判断时间点数量是否超过1440,是则直接返回0。2. 将时间点转换为从当天0点开始计算的分钟数,并按分钟数进行排序。3. 遍历排序后的时间点,计算相邻时间点的分钟差,并记录最小差值。4. 计算最后一个时间点与第一个时间点跨天的分钟差,更新最小差值。

时间复杂度: O(n log n)

空间复杂度: O(log n)

def getMinutes(t: str) -> int:
    # 将HH:MM格式的时间转换为从0点开始的总分钟数
    return (int(t[0]) * 10 + int(t[1])) * 60 + int(t[3]) * 10 + int(t[4])

class Solution:
    def findMinDifference(self, timePoints: List[str]) -> int:
        n = len(timePoints)
        # 如果时间点数超过所有可能的分钟数,必有重复,最小差为0
        if n > 1440:
            return 0
        # 按时间排序
        timePoints.sort()
        ans = 1440 # 最大可能的时间差(一整天的分钟数)
        t0Minutes = getMinutes(timePoints[0]) # 第一个时间点的分钟数
        preMinutes = t0Minutes # 前一个时间点的分钟数
        for i in range(1, n):
            minutes = getMinutes(timePoints[i]) # 当前时间点的分钟数
            ans = min(ans, minutes - preMinutes) # 更新最小时间差
            preMinutes = minutes # 更新前一个时间点
        # 计算首尾时间点跨天的时间差
        ans = min(ans, t0Minutes + 1440 - preMinutes)
        return ans

Explore

在此题解中,初始化最小差值为1440(一整天的分钟数)是有效的,并适用于所有情况。这是因为任何两个不同时间点之间的差值都不可能超过1440分钟,这是因为一天中只有1440分钟。因此,将最小差值初始化为1440是合理的,因为在比较过程中,任何实际出现的时间差都会小于或等于1440,从而确保这个初始值能够被任何两个相邻时间点的实际差值所更新。如果没有时间点差值超过这个初始值,说明所有时间点相同,最小差值实际上应为0,但这种情况在题解的逻辑中已经被提前处理(通过判断时间点数是否超过1440来直接返回0)。