题目描述
思路解析动画文字版
记住这套「换算分钟 → 排序 → 相邻求差 → 再补环形那一对」,下面每一帧都在套它。
把第 0 个时间 23:50 折算成分钟:23 小时是 1380 分钟,再加 50 分,得 1430。灰色是还没换算的,绿色是已经换好的。
把第 1 个时间 00:10 折算成分钟:0 小时是 0 分钟,再加 10 分,得 10。灰色是还没换算的,绿色是已经换好的。
把第 2 个时间 12:00 折算成分钟:12 小时是 720 分钟,再加 0 分,得 720。灰色是还没换算的,绿色是已经换好的。
把第 3 个时间 06:30 折算成分钟:6 小时是 360 分钟,再加 30 分,得 390。灰色是还没换算的,绿色是已经换好的。
把第 4 个时间 18:45 折算成分钟:18 小时是 1080 分钟,再加 45 分,得 1125。灰色是还没换算的,绿色是已经换好的。
五个时间点都换成了分钟:1430、10、720、390、1125。现在它们还是输入的乱序,下一步排序。
从小到大排好序:10、390、720、1125、1430,对应时间是 00:10、06:30、12:00、18:45、23:50。排序后,差最小的两个时间一定是挨着的,这是这套解法的根。
开始扫相邻对。两个指针指住排序后挨着的一对,从第 0、1 个起,一路往右滑。best 用来记一路见过的最小差,现在还空着。
看排序后挨着的第 0、1 个:00:10(10 分)和 06:30(390 分)。它俩相邻,差就是 390 减 10,下一帧算出来。
这一对相差 380 分钟。比之前的最小还小,best 刷新成 380。
看排序后挨着的第 1、2 个:06:30(390 分)和 12:00(720 分)。它俩相邻,差就是 720 减 390,下一帧算出来。
这一对相差 330 分钟。比之前的最小还小,best 刷新成 330。
看排序后挨着的第 2、3 个:12:00(720 分)和 18:45(1125 分)。它俩相邻,差就是 1125 减 720,下一帧算出来。
这一对相差 405 分钟。没有目前的 best=330 小,best 不变。
看排序后挨着的第 3、4 个:18:45(1125 分)和 23:50(1430 分)。它俩相邻,差就是 1430 减 1125,下一帧算出来。
这一对相差 305 分钟。比之前的最小还小,best 刷新成 305。
相邻对扫完了,但还漏了一对:排在最后的 23:50 和排在最前的 00:10。它俩看着隔了大半天,可时间是环形的,跨过午夜其实可能很近,必须补这一刀。
跨午夜的差怎么算:从最晚的 1430 分走到午夜(第 1440 分),再走到最早的 10 分,合起来是 10 加 1440 减 1430,等于 20 分钟。也就是 23:50 到第二天 00:10 只隔 20 分钟。
环形差 20 分钟,比相邻里最小的 305 还小,best 刷新成 20。这正是这道题最容易漏的一对。
扫完所有相邻对加上环形那一对,最小的是绿色高亮的这一对 23:50 和 00:10,跨午夜只差 20 分钟。答案就是 20。
边界先想清:跨午夜、有重复、超过 1440 个。
两个高频追问:计数桶 O(n) 优化、鸽巢特判的来历。
参考代码
from __future__ import annotationsfrom typing import *from collections import *from functools import *from itertools import *from math import *from heapq import *from bisect import *class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = rightclass ListNode: def __init__(self, val=0, next=None): self.val = val self.next = nextclass Solution: def findMinDifference(self, timePoints: List[str]) -> int: if len(timePoints) > 1440: return 0 nums = sorted(int(x[:2]) * 60 + int(x[3:]) for x in timePoints) nums.append(nums[0] + 1440) return min(b - a for a, b in pairwise(nums))复杂度
- 时间:O(n log n),瓶颈在排序;换算和扫相邻都是 O(n)
- 空间:O(n),存 n 个分钟数(含一个哨兵)
易错点
面试追问把动画讲成自己的话
追问能不能不排序、用计数桶做到 O(n)?
追问为什么时间点超过 1440 个就能直接返回 0?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
任务调度器
LeetCode 621 · 中等 · 沿着 贪心套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题