题目描述
思路解析动画文字版
核心就一句话:枚举 24 种排法,合法的留下,取最大。下面每一帧都在套它。
这是手里的 4 个数字。接下来把它们摆成「时-时-分-分」四个位置,逐一试遍 24 种排法。
排成 12:34:小时 12 没超 23、分钟 34 没超 59,合法。它比之前见过的都大,最大时间刷新为 12:34。
排成 12:43:小时 12 没超 23、分钟 43 没超 59,合法。它比之前见过的都大,最大时间刷新为 12:43。
排成 13:24:小时 13 没超 23、分钟 24 没超 59,合法。它比之前见过的都大,最大时间刷新为 13:24。
排成 13:42:小时 13 没超 23、分钟 42 没超 59,合法。它比之前见过的都大,最大时间刷新为 13:42。
排成 14:23:小时 14 没超 23、分钟 23 没超 59,合法。它比之前见过的都大,最大时间刷新为 14:23。
排成 14:32:小时 14 没超 23、分钟 32 没超 59,合法。它比之前见过的都大,最大时间刷新为 14:32。
排成 21:34:小时 21 没超 23、分钟 34 没超 59,合法。它比之前见过的都大,最大时间刷新为 21:34。
排成 21:43:小时 21 没超 23、分钟 43 没超 59,合法。它比之前见过的都大,最大时间刷新为 21:43。
排成 23:14:小时 23 没超 23、分钟 14 没超 59,合法。它比之前见过的都大,最大时间刷新为 23:14。
排成 23:41:小时 23 没超 23、分钟 41 没超 59,合法。它比之前见过的都大,最大时间刷新为 23:41。
排成 24:13:小时已经到 24,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 24:31:小时是 24,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 31:24:前两位当小时是 31,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 31:42:小时凑成 31,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 32:14:小时部分是 32,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 32:41:小时已经到 32,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 34:12:小时是 34,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 34:21:前两位当小时是 34,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 41:23:小时凑成 41,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 41:32:小时部分是 41,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 42:13:小时已经到 42,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 42:31:小时是 42,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 43:12:前两位当小时是 43,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
排成 43:21:小时凑成 43,超过 23,这种排法不是合法时间,直接淘汰。当前最大仍是 23:41。
24 种排法试完,所有合法时间里 23:41 最大,它就是答案。其余排法要么超时、要么更小,都被它压下去。
边界先想清:可能完全无解返回空串,也可能只有唯一一种合法排法。
两个高频追问:复杂度为何是常数,以及倒扫时刻这种等价写法。
参考代码
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 largestTimeFromDigits(self, arr: List[int]) -> str: cnt = [0] * 10 for v in arr: cnt[v] += 1 for h in range(23, -1, -1): for m in range(59, -1, -1): t = [0] * 10 t[h // 10] += 1 t[h % 10] += 1 t[m // 10] += 1 t[m % 10] += 1 if cnt == t: return f'{h:02}:{m:02}' return ''复杂度
- 时间:O(1),排法固定 24 种,每种校验是常数
- 空间:O(1),只用几个变量记当前最大
易错点
面试追问把动画讲成自己的话
追问这题为什么说是常数时间复杂度?
追问Python 参考解为什么从 23:59 倒着扫,而不枚举排列?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
连续差相同的数字
LeetCode 967 · 中等 · 沿着 回溯套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题