LeetCode 401 - 二进制手表
这道题其实是一个非常典型的组合枚举问题。我们有 10 个 LED 灯,其中 4 个代表小时(范围 0–11),6 个代表分钟(范围 0–59),题目要求我们给出所有“亮灯数 = turnedOn”时的合法时间组合。看起来像是个电子表的问题,但本质上是二进制位运算与组合的应用。我们可以把“亮灯的数量”理解成“二进制 1 的个数”,所以整个题的核心思路就是:枚举所有可能的小时和分钟组合,筛选出二进制中
摘要
这道题其实是一个非常典型的组合枚举问题。我们有 10 个 LED 灯,其中 4 个代表小时(范围 0–11),6 个代表分钟(范围 0–59),题目要求我们给出所有“亮灯数 = turnedOn”时的合法时间组合。
看起来像是个电子表的问题,但本质上是二进制位运算与组合的应用。我们可以把“亮灯的数量”理解成“二进制 1 的个数”,所以整个题的核心思路就是:枚举所有可能的小时和分钟组合,筛选出二进制中 1 的个数刚好等于 turnedOn
的情况。
描述
在一个二进制手表上:
- 上面 4 个 LED 代表小时(0~11),用 4 位二进制来表示;
- 下面 6 个 LED 代表分钟(0~59),用 6 位二进制来表示。
举例:
- 小时 4 =
0100
- 分钟 51 =
110011
那么时间是"4:51"
。
我们要做的就是:给定亮着的灯的数量 turnedOn
,输出所有符合这个亮灯数的时间,比如当 turnedOn = 1
时,只有一个 LED 亮着,那么可能是 "1:00"
、"0:08"
、"0:32"
等。
题解答案
最直观的想法是暴力枚举所有可能的小时和分钟:
- 小时范围
[0, 11]
- 分钟范围
[0, 59]
对于每个组合:
- 计算当前小时和分钟的二进制表示;
- 求两者中 1 的总数;
- 如果等于
turnedOn
,就把格式化后的时间加入结果。
Swift 提供了内置的函数 nonzeroBitCount
,可以直接获取一个整数的二进制中 1 的数量,非常适合这种情况。
题解代码分析
下面我们来写一个完整可运行的 Swift Demo:
import Foundation
class Solution {
func readBinaryWatch(_ turnedOn: Int) -> [String] {
var result: [String] = []
// 枚举小时和分钟
for hour in 0..<12 {
for minute in 0..<60 {
// 计算二进制中1的个数
if hour.nonzeroBitCount + minute.nonzeroBitCount == turnedOn {
// 格式化时间
let time = String(format: "%d:%02d", hour, minute)
result.append(time)
}
}
}
return result
}
}
// 示例测试
let sol = Solution()
print(sol.readBinaryWatch(1))
print(sol.readBinaryWatch(2))
print(sol.readBinaryWatch(9))
代码解析
hour.nonzeroBitCount
:这是 Swift 的一个非常实用的属性,用来计算整数中 1 的数量,相当于 C++ 的__builtin_popcount
。- 我们遍历所有可能的时间组合,共
12 * 60 = 720
种。 - 只要当前时间的二进制亮灯数与输入的
turnedOn
相同,就把这个时间加入结果。 String(format: "%d:%02d", hour, minute)
保证分钟是两位数格式,比如"1:05"
。
整个逻辑非常直观,核心是利用二进制的位数统计来筛选。
示例测试及结果
示例 1
输入:
sol.readBinaryWatch(1)
输出:
["0:01","0:02","0:04","0:08","0:16","0:32",
"1:00","2:00","4:00","8:00"]
解释:
- 当只有一个灯亮时,可能是某个分钟灯亮,也可能是某个小时灯亮。
示例 2
输入:
sol.readBinaryWatch(9)
输出:
[]
解释:
手表最多有 10 个灯,小时最多 4 位 + 分钟 6 位;如果亮 9 个灯,不可能构成合法时间。
示例 3
输入:
sol.readBinaryWatch(3)
输出示例:
["0:07", "0:11", "1:03", "2:05", "3:00", "4:06", "8:03", ...]
时间复杂度
- 枚举所有小时(12 种)和分钟(60 种),总共 720 次循环。
- 每次循环只做常数级别操作(位数统计 + 拼接字符串)。
所以时间复杂度为 O(720),即 O(1) 常数级。
空间复杂度
只使用了一个结果数组,没有额外结构。
空间复杂度为 O(1)(不计输出结果)。
总结
这题是一个非常典型的“枚举 + 二进制位计数”问题。
虽然题目看起来和时间有关,但其实本质是一个组合问题:有 10 个灯,开了几个,就代表一个唯一的小时+分钟组合。
更多推荐
所有评论(0)