LeetCode题练习与总结:最小时间差--539

一、题目描述

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

示例 1:

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

示例 2:

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

提示:

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

二、解题思路

  1. 将所有时间转换为从"00:00"开始的分钟数。例如,"01:00"转换为60分钟,"12:34"转换为754分钟。
  2. 将转换后的分钟数排序。
  3. 计算排序后相邻时间的分钟差,并记录最小差值。
  4. 由于时间是一个环形的,比如"23:59"和"00:00"之间的差值需要特别计算,所以还需要计算列表中第一个和最后一个时间的差值。
  5. 返回记录的最小差值。

三、具体代码

import java.util.Collections;
import java.util.List;

public class Solution {
    public int findMinDifference(List<String> timePoints) {
        // 如果时间点数量超过一天中的分钟数,则必定存在重复时间,直接返回0
        if (timePoints.size() > 1440) return 0;

        // 将时间转换为分钟数并排序
        Collections.sort(timePoints, (a, b) -> {
            int diff = convertToMinutes(a) - convertToMinutes(b);
            return diff == 0 ? a.compareTo(b) : diff; // 如果分钟数相同,则保持原有顺序
        });

        int minDifference = Integer.MAX_VALUE;
        int prevMinutes = convertToMinutes(timePoints.get(0));
        int firstMinutes = prevMinutes;

        // 遍历时间点,计算相邻时间点的分钟差
        for (int i = 1; i < timePoints.size(); i++) {
            int currMinutes = convertToMinutes(timePoints.get(i));
            minDifference = Math.min(minDifference, currMinutes - prevMinutes);
            prevMinutes = currMinutes;
        }

        // 计算第一个和最后一个时间点的分钟差,考虑环形时间
        minDifference = Math.min(minDifference, firstMinutes + 1440 - prevMinutes);

        return minDifference;
    }

    // 将时间转换为从"00:00"开始的分钟数
    private int convertToMinutes(String time) {
        String[] parts = time.split(":");
        return Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]);
    }
}

这段代码首先定义了一个辅助方法convertToMinutes,用于将时间字符串转换为从"00:00"开始的分钟数。然后在findMinDifference方法中,先将时间点列表排序,接着计算相邻时间点的分钟差,并记录最小差值。最后,还需要计算列表中第一个和最后一个时间点的差值,并考虑环形时间的情况。如果时间点数量超过一天中的分钟数,则直接返回0,因为这意味着必定存在重复的时间点。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • convertToMinutes 方法:该方法对每个时间字符串执行一次,它包括字符串分割和整数解析操作。字符串分割是 O(1) 操作,因为时间字符串的长度是固定的(“HH:MM”),整数解析也是 O(1) 操作。因此,convertToMinutes 方法的时间复杂度是 O(1)。

  • Collections.sort 方法:对时间点列表进行排序,排序算法通常是 O(n log n),其中 n 是列表中时间点的数量。

  • 遍历时间点列表并计算最小差值:这个操作是 O(n),因为每个时间点只被访问一次。

综合以上步骤,总的时间复杂度是 O(n log n) + O(n) = O(n log n),因为排序的时间复杂度通常是主导的。

2. 空间复杂度
  • convertToMinutes 方法:该方法使用了固定数量的额外空间(用于存储分割后的字符串数组),因此空间复杂度是 O(1)。

  • 排序:如果使用的是类似于快速排序的算法,那么空间复杂度是 O(log n),这是因为递归调用栈的深度。

  • 额外变量:minDifferenceprevMinutes 和 firstMinutes 是几个整型变量,它们占用 O(1) 的空间。

综上所述,总的空间复杂度是 O(log n),主要由排序算法的空间复杂度决定。

五、总结知识点

  1. 类定义:定义了一个名为 Solution 的公共类,这是 Java 中的基本面向对象编程结构。

  2. 方法定义:定义了一个公共方法 findMinDifference 和一个私有辅助方法 convertToMinutes,分别用于查找最小时间差和将时间字符串转换为分钟数。

  3. 接口和泛型:使用了 List 接口和泛型 <String> 来定义方法参数 timePoints,表明这是一个字符串列表。

  4. 异常处理:虽然没有显式地捕获异常,但 Integer.parseInt 方法可能会抛出 NumberFormatException,通常在实际应用中应该对此进行异常处理。

  5. 字符串操作:使用了 String.split 方法来分割字符串,并使用 String[] 数组来存储分割后的结果。

  6. 数学运算:执行了基本的算术运算,如乘法、加法和减法,用于时间转换和差值计算。

  7. 逻辑判断:使用了 if 语句来检查时间点数量是否超过一天中的分钟数,从而直接返回 0。

  8. 排序:使用了 Collections.sort 方法来对时间点列表进行排序,并自定义了一个比较器来根据时间转换为分钟数进行排序。

  9. 循环遍历:使用 for 循环遍历列表中的时间点,并计算相邻时间点之间的最小差值。

  10. 最小值计算:使用 Math.min 方法来计算并更新最小时间差。

  11. 常量:使用了 Integer.MAX_VALUE 作为初始的最小时间差,确保任何实际的时间差都会小于此值。

  12. 时间转换:理解了 24 小时制时间与分钟数之间的转换关系,即一天有 1440 分钟。

  13. 环形时间差:考虑了时间差在一天结束时可能出现的环形情况,即第一个时间点与最后一个时间点之间的差值。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值